【问题标题】:Are tests executed in parallel in Go or one by one?测试是在 Go 中并行执行还是一个接一个地执行?
【发布时间】:2017-11-03 15:31:31
【问题描述】:

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

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

【问题讨论】:

    标签: unit-testing testing go


    【解决方案1】:

    测试起来真的很容易:

    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 标志指定其中有多少可以并行运行。如果你用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 以查看完整的测试标志列表。

    【讨论】:

      【解决方案2】:

      默认情况下,一个包的所有测试都是按顺序运行的。

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

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

      猜你喜欢
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 2013-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-07
      • 2022-01-11
      相关资源
      最近更新 更多