Go 测试用例

Table of Contents

go help test 查看说明,更多: https://golang.org/pkg/testing/

1 基础

  • go test 命令会自动执行带有 func TestXxx(*testing.T) 格式的函数。
  • _test.go 结尾的文件会被认为是测试用例文件,其中包含 TestXxx 这样的测试用例。
  • *_test 的包在执行 test 的时候会重新编译,每个 package 都是会生成单独的二进制不会干扰。以 "_" 或者 "." 开始的文件会被自动忽略。 包括 "_test.go" 。
  • go 工具会自动忽略 "testdata" 文件夹,可用来放置一些测试所需要的辅助数据。
  • 测试文件和要被测试的文件放在同一个包中,比如 redis.goredis_test.go

Go test 的两种运行模式:

  1. 针对本地目录 go test 或者 go test -v ,这种情况下只会运行当前目录下的测试;
  2. 针对包列表,设置包参数 go test math 或者 go test ./.. 甚至是 go test . ,这种情况下它会编译命令行指定的每一个包,全部执行测试

在第二种情况下,go test 会缓存成成功执行的包的测试结果避免重复执行测试用例,输出结果会以 '(cached)' 标识。 但是在指定了测试参数,比如 -cpu, -list, -parallel, -run, -short, -v 等将不会被缓存。管用的一种显式禁用缓存的方法是使用 -count=1 参数。

Benchmarks(基准测试)

  • 在 "go test" 命令指定了 bench 标识的情况下,会运行 func BenchmarkXxx(*testing.B) 格式的函数。基准测试是按照顺序执行的。
  • 基准测试会单单独输出测试结果(执行 b.N 次)。

Examples

Example 函数包含一个总结行,以 "Output:" 开始,会比较实际输出的结果是否一致。Example 函数以 Example 开始。没有输出注释 // Output: 的 Example 函数不会被执行。

Example 函数也有自己的命名约定,函数是 F,类型是 T,类型上的方法是 T_M .

Skipping

通过调用 *T 或者 *BSkip 方法可以跳过测试。

子测试和子基准测试

对于需要有资源安装和清理的测试用例,子测试很有用。

func TestFoo(t *testing.T) {
    // <setup code>
    t.Run("A=1", func(t *testing.T) { ... })
    t.Run("A=2", func(t *testing.T) { ... })
    t.Run("B=1", func(t *testing.T) { ... })
    // <tear-down code>
}
  • 每个子测试或者子基准测试,都有一个唯一的名字。可以在执行测试的时候通过名字筛选测试。比如 go test -run Foo/A=

Main

很多时候在测试程序开始和结束有额外的安装和卸载。

func TestMain(m *testing.M)

那么会在执行测试时先调用 TestMain(m) 而不是其它的测试用例。所有的测试用例会在 m.Run() 中执行,那么在它之前你可以做一些初始化,之后做清理工作。 最简单的 TestMain:

func TestMain(m *testing.M) {
    // call flag.Parse() here if TestMain uses flags
    os.Exit(m.Run())
}

在每一个 test 文件中都可以有一个 TestMain,看起来更适合做初始化和销毁工作。

2 常用命令

  • 运行所有测试用例: go test -count=1 -v ./...
  • 运行单个模块: go test -count=1 -v module_name
  • 运行单个模块的单个 case: go test -count=1 -v module_name -run.test funcName

First created: 2020-05-15 11:05:17
Last updated: 2020-07-16 Thu 15:04
Power by Emacs 26.3 (Org mode 9.3.7)