在Go编程语言(Golang)的上下文中,该t.Parallel()函数经常用于测试。在 Go 中编写测试时,该testing包提供了一种T类型,该类型具有用于管理和报告测试状态的方法。该t.Parallel()方法用于将测试或子测试标记为能够与其他测试并行运行。
这是一个简短的解释:
- t.Parallel():将调用测试或子测试标记为能够与其他测试并行运行。当测试或子测试被标记为并行时,它可以与其他并行测试同时执行,从而可能缩短测试执行时间。
Go语言中的t.Parallel()函数可以将测试用例标记为并行执行,从而提高测试的速度。
- 这个函数在处理大型测试套件时特别有用。然而,并不是所有的测试套件都适合并行执行,对于小型测试套件来说,可能会增加额外的开销。
- 另外,使用t.Parallel()需要注意一些问题,比如数据库共享、事务死锁和日志输出。
package mypackage |
在上面的示例中,在函数t.Parallel()内调用TestSomething来指示该测试可以与其他并行测试同时运行。
使用之前:
$ go test ./server/api -count=1 |
使用之后:
$ go test ./server/api -count=1 |
这些测试已经相当快了
测试goroutine
我们的测试使用goleak来检测任何意外泄漏的goroutine,这是我推荐的做法,因为泄漏goroutine却没有意识到它很容易成为 Go 的顶级枪械之一。
以前,我们有一个模式,其中每个测试用例都会检查自身是否有Goroutine泄漏,但是添加t.Parallel()打破了该模式,因为并行运行的测试用例会将彼此的Goroutine检测为泄漏。
解决方法是使用 goleak 的内置TestMain 包装器:
func TestMain(m *testing.M) { |
泄漏的goroutine只能在包级别的粒度上检测到,但只要您从无泄漏的基线开始,就足以检测回归。
总的来说
使用t.Parallel()需要根据具体情况进行考虑:
- Go语言的并行测试功能通过t.Parallel()可以让特定测试用例在同一个包内并行运行,提高测试速度。
- 在大型包中使用t.Parallel()可以显著减少测试时间,对于频繁运行测试的包来说,速度提升对于开发体验非常重要。
- 添加t.Parallel()可以保持测试套件的快速运行,尤其是在包变得庞大时,而且在测试用例中一开始就加入t.Parallel()比后期添加更容易。
- 在测试中需要“t.Parallel()”,但在子测试中不需要
普遍使用 . 并不完全符合 Go 约定t.Parallel()。也就是说,它减少了我们对大型包的测试迭代时间 30-40%,这足以是一个开发胜利,我个人打算将它用于未来的 Go 项目。
尽管提高测试速度是其主要优点,但与go test . -race它结合使用时,实际上可以帮助解决一些棘手的并行安全错误,而这些错误仅通过顺序测试运行无法捕获。这是一个很大的优势,因为整个类别的错误在生产中很难调试。
激活t.Parallel()现有项目的所有地方可能是一件大事,但从一开始就将其集成,持续成本非常低,并且可能会在以后产生巨大的好处。