跳到主要内容

Go 测试

本章将介绍 Go 的测试框架。

测试基础

创建测试文件

测试文件以 _test.go 结尾:

// math.go
package math

func Add(a, b int) int {
return a + b
}

// math_test.go
package math

import "testing"

func TestAdd(t *testing.T) {
result := Add(2, 3)
expected := 5

if result != expected {
t.Errorf("Add(%d, %d) = %d; want %d", 2, 3, result, expected)
}
}

运行测试

# 运行当前包所有测试
go test

# 运行所有测试
go test ./...

# 详细输出
go test -v

# 显示覆盖率
go test -cover

# 生成覆盖率报告
go test -coverprofile=coverage.out
go tool cover -html=coverage.out

断言函数

Go 标准库没有断言,需要自己编写或使用第三方库:

func assertEqual(t *testing.T, got, expected interface{}) {
if got != expected {
t.Errorf("got %v, want %v", got, expected)
}
}

func assertTrue(t *testing.T, condition bool, msg string) {
if !condition {
t.Errorf("assertion failed: %s", msg)
}
}

表驱动测试

func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"正数相加", 2, 3, 5},
{"负数相加", -1, -1, -2},
{"零", 0, 5, 5},
{"正负相加", -5, 10, 5},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := Add(tt.a, tt.b)
if result != tt.expected {
t.Errorf("got %d, want %d", result, tt.expected)
}
})
}
}

基准测试

func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(2, 3)
}
}

运行:

go test -bench=.
go test -bench=BenchmarkAdd -benchmem

示例函数

func ExampleAdd() {
sum := Add(1, 2)
fmt.Println(sum)
// Output: 3
}

小结

  1. 测试文件_test.go 结尾
  2. 测试函数func TestXxx(t *testing.T)
  3. 基准测试func BenchmarkXxx(b *testing.B)
  4. 表驱动测试:使用结构体切片
  5. 示例函数:可作为文档和测试

练习

  1. 编写一个函数的单元测试
  2. 使用表驱动测试改进测试
  3. 编写基准测试对比性能