测试是在Go中逐个执行还是逐个执行?

时间:2017-06-02 09:19:21

标签: unit-testing testing go

我有一个带有单元测试的Go文件,其中一些使用公共变量。另一个全局变量用于我正在测试的代码中。所有这些都可能导致问题。

在Go中,当我们执行位于同一文件中的测试时,它们是如何运行的?并行或下一个在上一个完成之前不会启动?

2 个答案:

答案 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。然后Test1Test2运行 parallel

有一些测试标志可以控制并行执行。例如,-parallel标志指定其中有多少可以并行运行。如果您使用go test -parallel=1执行该输出,则输出将再次变为顺序,但顺序将为Test3Test1Test2

另请注意Go 1.7 introduced subtests and subbenchmarks。您可以在博文Using Subtests and Sub-benchmarks中了解更多相关信息:

  

在Go 1.7中,testing包在TB类型上引入了一种Run方法,允许创建子测试和子基准。子测试和子基准测试的引入可以更好地处理故障,对从命令行运行的测试进行细粒度控制,并行控制,并且通常可以使代码更简单,更易于维护。

子测试和子基准测试可以并行运行,并且有许多标志可以控制它们的执行,例如-parallel-p-cpu。运行go help testflag以查看测试标志的完整列表。

答案 1 :(得分:0)

默认情况下, 包中的所有测试均按顺序运行。

默认情况下,所有测试集都是并行运行的。

如果您使用默认值并且具有针对通用持久层(如rdbms)进行测试的其他程序包,则可能会导致问题。如果您遇到这种情况,则运行go test ./... -p 1将阻止不同的测试套件同时运行。