首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么对t.Cleanup有用?

什么对t.Cleanup有用?
EN

Stack Overflow用户
提问于 2020-05-05 08:39:50
回答 3查看 8K关注 0票数 14

问题

我想知道Go1.14中引入的t.Cleanup的用例。与使用延迟相比,t.Cleanup的方便性是什么?

https://golang.org/pkg/testing/#T.Cleanup

  • Sample

例如,假设我们创建了一个临时目录,当我们测试它时,我们希望删除我们创建的临时目录。

t.Cleanup可以用于编写测试,如下所示,但它也可以作为defer os.RemoveAll(tempDir)工作。

代码语言:javascript
复制
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...
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-05-05 09:14:14

如果您的测试恐慌,清理功能也会被调用,所以在您的情况下,两者都会工作。

如果您的测试调用其他函数,并传递T.Cleanup(),那么使用testing.T的优点就变得很明显了。显然,在这些函数中使用defer将在这些函数返回之前执行,但是如果您使用T.Cleanup()注册清理函数,那么它们只会在测试结束时被调用。

T.Cleanup()看作是defer的“改进”和扩展版本。它还记录了传递的函数是用于清理目的的。

票数 22
EN

Stack Overflow用户

发布于 2020-05-05 09:08:13

当测试不关心资源本身时,t.Cleanup对于清理由助手函数分配的资源非常有用。

示例

考虑测试服务层。服务使用*sql.DB,但不自己创建它。

代码语言:javascript
复制
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.CleanupnewTestSubject将不得不返回(*domain.Service, *sql.DB),泄露domain.Service的建设细节。

票数 15
EN

Stack Overflow用户

发布于 2020-10-02 21:20:11

除了其他人所指出的,t.Cleanup()在处理并行子测试时也很有用,在并行子测试中,清理应该只在所有子测试完成之后才能运行。考虑一下

代码语言:javascript
复制
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()之前,解决这个问题的一种方法是将子测试封装在另一个测试上。

代码语言:javascript
复制
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()它会变得更好

代码语言:javascript
复制
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()
      (...)
   })
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61609085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档