且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在Go中分离单元测试和集成测试

更新时间:2022-10-17 22:10:12

@ Ainar-G提出了几种伟大的模式来分离测试。

SoundCloud的这组Go实践 a>建议使用构建标记(在构建包的构建约束部分中描述))选择要运行的测试:


编写一个integration_test.go,并给它一个集成的构建标记。为服务地址和连接字符串等事物定义(全局)标志,并在您的测试中使用它们。

  // +构建集成

var fooAddr = flag.String(...)

func TestToo(t * testing.T){
f,err:= foo.Connect(* fooAddr)
// ...
}

go test take build tags就像go build一样,所以你可以调用 go test -tags = integration 。它还综合了一个调用flag.Parse的包main,因此任何已声明和可见的标记都将被处理并可用于您的测试。

作为一个类似的选项,您也可以使用构建条件 // + build!unit 来默认运行集成测试,然后通过运行
$ b @adamc评论:

>对于任何尝试使用构建标记的人来说,重要的是 // +构建测试注释是文件中的第一行,并且在后面包含一个空行注释,否则 -tags 命令将忽略该指令。另外,构建注释中使用的标记不能有一个破折号,尽管下划线是允许的。例如, // +构建unit-tests 不起作用,而 // + build unit_tests will。 p>

Is there an established best practice for separating unit tests and integration tests in GoLang (testify)? I have a mix of unit tests (which do not rely on any external resources and thus run really fast) and integration tests (which do rely on any external resources and thus run slower). So, I want to be able to control whether or not to include the integration tests when I say go test.

The most straight-forward technique would seem to be to define a -integrate flag in main:

var runIntegrationTests = flag.Bool("integration", false
    , "Run the integration tests (in addition to the unit tests)")

And then to add an if-statement to the top of every integration test:

if !*runIntegrationTests {
    this.T().Skip("To run this test, use: go test -integration")
}

Is this the best I can do? I searched the testify documentation to see if there is perhaps a naming convention or something that accomplishes this for me, but didn't find anything. Am I missing something?

@Ainar-G suggests several great patterns to separate tests.

This set of Go practices from SoundCloud recommends using build tags (described in the "Build Constraints" section of the build package) to select which tests to run:

Write an integration_test.go, and give it a build tag of integration. Define (global) flags for things like service addresses and connect strings, and use them in your tests.

// +build integration

var fooAddr = flag.String(...)

func TestToo(t *testing.T) {
    f, err := foo.Connect(*fooAddr)
    // ...
}

go test takes build tags just like go build, so you can call go test -tags=integration. It also synthesizes a package main which calls flag.Parse, so any flags declared and visible will be processed and available to your tests.

As a similar option, you could also have integration tests run by default by using a build condition // +build !unit, and then disable them on demand by running go test -tags=unit.

@adamc comments:

For anyone else attempting to use build tags, it's important that the // +build test comment is the first line in your file, and that you include a blank line after the comment, otherwise the -tags command will ignore the directive.

Also, the tag used in the build comment cannot have a dash, although underscores are allowed. For example, // +build unit-tests will not work, whereas // +build unit_tests will.