#表格驱动测试
Go 项目里非常常见的一种测试写法叫表格驱动测试。
它适合测试多个输入和输出。
#一、普通写法的问题
func TestAdd(t *testing.T) {
if Add(1, 2) != 3 {
t.Fatal("case 1 failed")
}
if Add(2, 3) != 5 {
t.Fatal("case 2 failed")
}
if Add(-1, 1) != 0 {
t.Fatal("case 3 failed")
}
}用例多了以后,可读性会变差。
#二、表格驱动写法
func TestAdd(t *testing.T) {
tests := []struct {
name string
a int
b int
want int
}{
{name: "positive", a: 1, b: 2, want: 3},
{name: "zero", a: -1, b: 1, want: 0},
{name: "negative", a: -1, b: -2, want: -3},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Add(tt.a, tt.b)
if got != tt.want {
t.Fatalf("Add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.want)
}
})
}
}结构:
| 字段 | 作用 |
|---|---|
name | 用例名称 |
a / b | 输入 |
want | 期望结果 |
t.Run 会给每个用例创建子测试。
#三、测试错误
被测函数:
func Divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("除数不能为 0")
}
return a / b, nil
}测试:
func TestDivide(t *testing.T) {
tests := []struct {
name string
a int
b int
want int
wantErr bool
}{
{name: "ok", a: 10, b: 2, want: 5, wantErr: false},
{name: "zero divisor", a: 10, b: 0, want: 0, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Divide(tt.a, tt.b)
if tt.wantErr {
if err == nil {
t.Fatal("expected error, got nil")
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got != tt.want {
t.Fatalf("got %d, want %d", got, tt.want)
}
})
}
}#四、适合表格驱动的场景
- 参数校验
- 字符串处理
- 金额计算
- 状态转换
- 错误分支
- API 响应结构转换
表格驱动测试的核心是:把不同场景变成一组清晰的数据。

