Overview

testing包为Go包的自动化测试提供了支持。它打算与“go test”命令一起使用,该命令可自动执行任何函数形式。

  1. func TestXxx((testing.T)

Xxx不能以小写字母开头。函数名用于标识测试程序。

在这些函数中,使用Error、Fail或相关函数来表示失败。要编写一个新的测试套件,创建一个以_test.go结尾的文件。包含这里描述的TestXxx函数。将该文件放在与正在测试的文件相同的包中。该文件将从常规的包构建中排除,但在运行“go test”命令时将包含该文件。要了解更多细节,请运行“go help test”和“go help testflag”。

一个简单的测试函数是这样的:

  1. func TestAbs(t *testing.T) {
  2. got := Abs(-1)
  3. if got != 1 {
  4. t.Errorf("Abs(-1) = %d; want 1", got)
  5. }
  6. }

Benchmarks

函数化

  1. func BenchmarkXxx(*testing.B)

被视为基准测试,并在提供-bench标志时由”go test”命令执行。
基准测试按顺序运行。

关于testing flags 描述,请参见 https://golang.org/cmd/go/#hdr-Testing_flags

benchmark 函数例子看起来像这样:

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

benchmark function 必须运行目标代码 b.N次。在基准测试执行过程中,b.N会被调整,直到基准测试函数持续足够长的时间以可靠地计时。输出

  1. BenchmarkRandInt-8 68453040 17.8 ns/op

意味着循环以每循环17.8 ns的速度运行68453040次。

如果一个基准测试在运行前需要一些昂贵的设置,计时器可能会被重置:

  1. func BenchmarkBigLen(b *testing.B) {
  2. big := NewBig()
  3. b.ResetTimer()
  4. for i := 0; i < b.N; i++ {
  5. big.Len()
  6. }
  7. }

如果基准测试需要在并行设置中测试性能,它可以使用RunParallel助手函数;这样的基准测试是为了与go test -cpu flag 一起使用:

  1. func BenchmarkTemplateParallel(b *testing.B) {
  2. templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
  3. b.RunParallel(func(pb *testing.PB) {
  4. var buf bytes.Buffer
  5. for pb.Next() {
  6. buf.Reset()
  7. templ.Execute(&buf, "World")
  8. }
  9. })
  10. }

Examples

该包还运行并验证示例代码。示例函数可能包括以“Output:”开头的结束行注释,并在运行测试时与函数的标准输出进行比较。(比较忽略了前导空格和尾随空格。)下面是一些例子:

  1. func ExampleHello() {
  2. fmt.Println("hello")
  3. // Output: hello
  4. }
  5. func ExampleSalutations() {
  6. fmt.Println("hello, and")
  7. fmt.Println("goodbye")
  8. // Output:
  9. // hello, and
  10. // goodbye
  11. }

注释前缀”无序输出:”类似于” output:”,但匹配任何行序:

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

没有输出注释的示例函数将被编译但不执行。

为程序包、函数F、类型T和类型T上的方法M声明示例的命名约定如下:

  1. func Example() { ... }
  2. func ExampleF() { ... }
  3. func ExampleT() { ... }
  4. func ExampleT_M() { ... }

package/type/function/method 多个实例函数可以通过在名称上追加明显的前缀来提供。前缀必须以小写字母开始。

  1. func Example_suffix() { ... }
  2. func ExampleF_suffix() { ... }
  3. func ExampleT_suffix() { ... }
  4. func ExampleT_M_suffix() { ... }

当整个测试文件包含单个示例函数、至少一个其他函数、类型、变量或常量声明,并且没有测试或基准函数时,它将作为示例呈现。

Skipping

可以通过调用T或B的Skip方法在运行时跳过测试或基准测试:

  1. func TestTimeConsuming(t *testing.T) {
  2. if testing.Short() {
  3. t.Skip("skipping test in short mode.")
  4. }
  5. ...
  6. }