贝利信息

如何使用Golang进行表格驱动测试_Golang table-driven测试示例

日期:2026-01-05 00:00 / 作者:P粉602998670
表格驱动测试是Go中通过结构体切片组织测试用例并遍历执行的模式。核心为定义含name、input、want等字段的结构体切片,用t.Run运行子测试,确保用例独立、可读、可维护。

什么是表格驱动测试(table-driven test)

Go 语言中没有内置的「数据驱动」或「参数化测试」语法,但用切片 + 结构体组合就能自然实现表格驱动测试。它的核心是把测试用例组织成 []struct{input, want, name string} 这样的切片,再用 for range 遍历执行——不是靠框架,而是靠 Go 的简洁语法和测试习惯。

如何写一个基础的表格驱动测试

以测试一个字符串首字母大写的函数为例,关键点在于:结构体字段命名清晰、t.Run() 使用子测试名、每个用例独立断言。

func TestCapitalize(t *testing.T) {
	tests := []struct {
		name  string
		input string
		want  string
	}{
		{"empty string", "", ""},
		{"single lowercase", "hello", "Hello"},
		{"already capitalized", "World", "World"},
		{"mixed case", "gOlang", "Golang"},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Capitalize(tt.input); got != tt.want {
				t.Errorf("Capitalize(%q) = %q, want %q", tt.input, got, tt.want)
			}
		})
	}
}

处理带 error 返回的函数

当被测函数返回 (string, error) 时,表格结构需增加 errWant 字段,并用 errors.Is()assert.Equal(t, err.Error(), ...) 判断错误内容——直接比较 err == nil 不够,因为错误值不支持指针等价判断。

func TestParseID(t *testing.T) {
	tests := []struct {
		name     string
		input    string
		want     int
		errWant  error
	}{
		{"valid number", "123", 123, nil},
		{"empty", "", 0, errors.New("empty ID")},
		{"non-digit", "abc", 0, errors.New("invalid digit")},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := ParseID(tt.input)
			if !errors.Is(err, tt.errWant) {
				t.Errorf("ParseID(%q) error = %v, want %v", tt.input, err, tt.errWant)
				return
			}
			if got != tt.want {
				t.Errorf("ParseID(%q) = %d, want %d", tt.input, got, tt.want)
			}
		})
	}
}

表格驱动测试容易被忽略的细节

真正影响可维护性的不是写法,而是组织方式和边界意识: