概述

func TestXxx(*testing.T)

测试函数的名字,Test要以大写开始。

测试的文件名是 xxx_test.go, “_test.go”结尾,文件内是TestXxx的函数。文件放在被测试模块同一目录。

具体错误可以用testing.T的Errorf来输出。

Benchmarks

func BenchmarkXxx(*testing.B)

go test -bench 将会依序运行benchmarks的用例。example:

func BenchmarkRandInt(b *testing.B) {
    for i := 0; i < b.N; i++ {
        rand.Int()
    }
}

b.N是动态改变的,直到运行次数足够多,能可靠计算每次耗时为止。会有如下输出:

BenchmarkRandInt-8   	68453040	        17.8 ns/op

如果benchmark需要平行测试性能,可以使用RunParallel函数,一般会go test -cpu flag一起用。

func BenchmarkTemplateParallel(b *testing.B) {
    templ := template.Must(template.New("test").Parse("Hello, !"))
    b.RunParallel(func(pb *testing.PB) {
        var buf bytes.Buffer
        for pb.Next() {
            buf.Reset()
            templ.Execute(&buf, "World")
        }
    })
}

Examples

func ExampleHello() {
    fmt.Println("hello")
    // Output: hello
}

func ExampleSalutations() {
    fmt.Println("hello, and")
    fmt.Println("goodbye")
    // Output:
    // hello, and
    // goodbye
}

Output那个注释是期待输出,对比结果时,会忽然前导和尾随空白。不按顺序时用Unordered output。

func ExamplePerm() {
    for _, value := range Perm(5) {
        fmt.Println(value)
    }
    // Unordered output: 4
    // 2
    // 1
    // 3
    // 0
}

Example中如果没有output的注释则只编译,不运行。

下面的suffix需要小写开头

func Example_suffix() { ... }
func ExampleF_suffix() { ... }
func ExampleT_suffix() { ... }
func ExampleT_M_suffix() { ... }

Skipping

路过。。

func TestTimeConsuming(t *testing.T) {
    if testing.Short() {
        t.Skip("skipping test in short mode.")
    }
    ...
}

Subtests and Sub-benchmarks

T和B类型中的Run可以定义子测试和子benchmarks,不需要为sub们定义函数。This enables uses like table-driven benchmarks and creating hierarchical tests. It also provides a way to share common setup and tear-down code:(这个可以使用表驱动benchmark和层级式测试,也能提供公共setup和tear-down代码)

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>
}

运行测试时,可以-run和-bench flags设置运行那些测试:

go test -run ''      # 运行所有测试
go test -run Foo     # 运行一级测试匹配 "Foo", 例如 "TestFooBar".
go test -run Foo/A=  # 运行一级测试匹配 "Foo", 运行二级测试匹配 "A=".
go test -run /A=1    # 运行所有一级测试, 运行二级测试匹配 "A=1".

子用例可以并行运行,父级仅在所有子用例运行完才完成。

func TestGroupedParallel(t *testing.T) {
    for _, tc := range tests {
        tc := tc // capture range variable
        t.Run(tc.Name, func(t *testing.T) {
            t.Parallel()
            ...
        })
    }
}

子测试间是并行的运行。

Main

有时需要在测试前或测试后有一些设置或tear-down的控制,或者控制那些代码需要在主线程运程,可以在一个文件内添加一个

func TestMain(m *testing.M)

有用的命令

运行所有当前目录和子目录的tests。

go test ./...