引入
写完代码不代表写对了,得验证。Go 内置了 testing 包,不需要第三方框架,写个 Test 函数就能跑测试。配合表驱动测试和 go test 命令,一套流程全搞定。
正文
定义
定义
Go 测试基于
testing包,测试文件以_test.go结尾,测试函数以Test开头,签名为func TestXxx(t *testing.T)。用go test命令运行。
语法
// add.go
func Add(a, b int) int {
return a + b
}
// add_test.go
func TestAdd(t *testing.T) {
got := Add(1, 2)
if got != 3 {
t.Errorf("Add(1, 2) = %d, want 3", got)
}
}例子
基本测试
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("got %d, want 5", result)
}
}t.Errorf() 报告失败但继续执行,t.Fatalf() 直接终止当前测试。
表驱动测试
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"正数", 1, 2, 3},
{"零", 0, 0, 0},
{"负数", -1, -2, -3},
{"混合", -1, 5, 4},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Add(tt.a, tt.b)
if got != tt.expected {
t.Errorf("Add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.expected)
}
})
}
}表驱动测试把多组用例塞进一个 slice,用 t.Run() 跑子测试,每个子测试独立命名,失败时一眼能看出哪组出了问题。
子测试
t.Run("空切片", func(t *testing.T) {
got := Sum([]int{})
if got != 0 {
t.Errorf("got %d, want 0", got)
}
})t.Run() 创建子测试,支持单独运行,方便定位失败用例。
跳过测试
func TestSlow(t *testing.T) {
if testing.Short() {
t.Skip("跳过慢速测试")
}
// 耗时操作
}用 t.Skip() 跳过不需要的测试,go test -short 时 testing.Short() 返回 true。
常见写法
| 写法 | 说明 |
|---|---|
go test | 运行当前包测试 |
go test ./… | 运行所有包测试 |
go test -v | 显示详细输出 |
go test -run TestXxx | 只跑指定测试 |
go test -short | 启用短模式 |
go test -cover | 显示覆盖率 |
t.Errorf() | 报告失败,继续执行 |
t.Fatalf() | 报告失败,终止测试 |
t.Skip() | 跳过当前测试 |
t.Run(name, fn) | 创建子测试 |
特点
- 测试文件必须以
_test.go结尾 - 测试函数必须以
Test开头,参数是*testing.T - 表驱动测试是 Go 社区的推荐写法,用例清晰易维护
t.Run()支持子测试,可以单独运行某个用例go test -cover能统计代码覆盖率- 测试函数里不需要手动调 main,
go test自动发现并运行
理解
Go 测试的设计非常务实:内置 testing 包,零依赖就能跑。表驱动测试把输入输出整理成表,新增用例只要加一行。go test 一条命令搞定编译、运行、报告,开发体验很顺滑。
引出
测试能验证功能对不对,但代码跑得快不快呢?接下来看 Go 基准测试,学习怎么用 Benchmark 函数测量性能。