我有一个带有单元测试的Go文件,其中一些使用公共变量。另一个全局变量用于我正在测试的代码中。所有这些都可能导致问题。
在Go中,当我们执行位于同一文件中的测试时,它们是如何运行的?并行或下一个在上一个完成之前不会启动?
答案 0 :(得分:5)
测试它真的很容易:
func Test1(t *testing.T) {
fmt.Println("Test1 start")
time.Sleep(time.Second * 2)
fmt.Println("Test1 end")
}
func Test2(t *testing.T) {
fmt.Println("Test2 start")
time.Sleep(time.Second * 2)
fmt.Println("Test2 end")
}
func Test3(t *testing.T) {
fmt.Println("Test3 start")
time.Sleep(time.Second * 2)
fmt.Println("Test3 end")
}
使用go test
运行它,输出显示它的顺序:
Test1 start
Test1 end
Test2 start
Test2 end
Test3 start
Test3 end
因此,正常测试会依次执行,但不要忘记订单未定义:How to run golang tests sequentially?
另请注意,测试函数可以标记自己有资格进行并行执行,并与使用T.Parallel()
方法执行相同操作的其他测试并行:
并行表示该测试将与其他并行测试并行(并且仅与其一起)。
因此,如果我们将上述测试代码修改为:
func Test1(t *testing.T) {
t.Parallel()
fmt.Println("Test1 start")
time.Sleep(time.Second * 2)
fmt.Println("Test1 end")
}
func Test2(t *testing.T) {
t.Parallel()
fmt.Println("Test2 start")
time.Sleep(time.Second * 2)
fmt.Println("Test2 end")
}
func Test3(t *testing.T) {
fmt.Println("Test3 start")
time.Sleep(time.Second * 2)
fmt.Println("Test3 end")
}
使用go test
再次运行,输出为:
Test3 start
Test3 end
Test1 start
Test2 start
Test2 end
Test1 end
这证明了什么?未定义测试顺序,此次首先执行Test3
。然后Test1
和Test2
运行 parallel 。
有一些测试标志可以控制并行执行。例如,-parallel
标志指定其中有多少可以并行运行。如果您使用go test -parallel=1
执行该输出,则输出将再次变为顺序,但顺序将为Test3
,Test1
,Test2
。
另请注意Go 1.7 introduced subtests and subbenchmarks。您可以在博文Using Subtests and Sub-benchmarks中了解更多相关信息:
在Go 1.7中,
testing
包在T和B类型上引入了一种Run方法,允许创建子测试和子基准。子测试和子基准测试的引入可以更好地处理故障,对从命令行运行的测试进行细粒度控制,并行控制,并且通常可以使代码更简单,更易于维护。
子测试和子基准测试可以并行运行,并且有许多标志可以控制它们的执行,例如-parallel
,-p
,-cpu
。运行go help testflag
以查看测试标志的完整列表。
答案 1 :(得分:0)
默认情况下, 包中的所有测试均按顺序运行。
默认情况下,所有测试集都是并行运行的。
如果您使用默认值并且具有针对通用持久层(如rdbms)进行测试的其他程序包,则可能会导致问题。如果您遇到这种情况,则运行go test ./... -p 1
将阻止不同的测试套件同时运行。