问题
我想知道Go1.14中引入的t.Cleanup的用例。与使用延迟相比,t.Cleanup的方便性是什么?
https://golang.org/pkg/testing/#T.Cleanup。
例如,假设我们创建了一个临时目录,当我们测试它时,我们希望删除我们创建的临时目录。
t.Cleanup可以用于编写测试,如下所示,但它也可以作为defer os.RemoveAll(tempDir)工作。
package mypkg
import (
"io/ioutil"
"os"
"testing"
)
func TestDirwalk(t *testing.T) {
tempDir, err := ioutil.TempDir(".", "temp")
if err != nil {
t.Errorf("create tempDir: %v", err)
}
t.Cleanup(func() { os.RemoveAll(tempDir) })
// something...
}发布于 2020-05-05 09:14:14
如果您的测试恐慌,清理功能也会被调用,所以在您的情况下,两者都会工作。
如果您的测试调用其他函数,并传递T.Cleanup(),那么使用testing.T的优点就变得很明显了。显然,在这些函数中使用defer将在这些函数返回之前执行,但是如果您使用T.Cleanup()注册清理函数,那么它们只会在测试结束时被调用。
将T.Cleanup()看作是defer的“改进”和扩展版本。它还记录了传递的函数是用于清理目的的。
发布于 2020-05-05 09:08:13
当测试不关心资源本身时,t.Cleanup对于清理由助手函数分配的资源非常有用。
示例
考虑测试服务层。服务使用*sql.DB,但不自己创建它。
package testutils
import (
"testing"
"my/db"
"my/domain"
)
func NewTestSubject(t *testing.T) *domain.Service {
t.Helper()
sqldb := newDatabase(t)
s, _ := domain.NewService(sqldb)
return s
}
func newDatabase(t *testing.T) *sql.DB {
t.Helper()
d, _ := db.Create()
t.Cleanup(func() {
d.Close()
})
}如果没有t.Cleanup,newTestSubject将不得不返回(*domain.Service, *sql.DB),泄露domain.Service的建设细节。
发布于 2020-10-02 21:20:11
除了其他人所指出的,t.Cleanup()在处理并行子测试时也很有用,在并行子测试中,清理应该只在所有子测试完成之后才能运行。考虑一下
func TestSomething(t *testing.T){
setup()
defer cleanup()
t.Run("parallel subtest 1", func(t *testing.T){
t.Parallel()
(...)
})
t.Run("parallel subtest 2", func(t *testing.T){
t.Parallel()
(...)
})
}这不起作用,因为测试函数将在子测试仍在运行时返回,从而导致子测试所需的资源被defer cleanup()删除。
在t.Cleanup()之前,解决这个问题的一种方法是将子测试封装在另一个测试上。
func TestSomething(t *testing.T){
setup()
defer cleanup()
t.Run("parallel tests", func(t *testing.T){
t.Run("subtest 1", func(t *testing.T){
t.Parallel()
(...)
})
t.Run("subtest 2", func(t *testing.T){
t.Parallel()
(...)
})
})
}这看起来不错,但是用t.Cleanup()它会变得更好
func TestSomething(t *testing.T){
setup()
t.Cleanup(cleanup)
t.Run("parallel subtest 1", func(t *testing.T){
t.Parallel()
(...)
})
t.Run("parallel subtest 2", func(t *testing.T){
t.Parallel()
(...)
})
}https://stackoverflow.com/questions/61609085
复制相似问题