关于 go-test-expert
go-test-expert 是面向 Go 开发者的测试技能,指导测试设计、执行与回归检查,涵盖表驱动测试及 HTTP、基准、模糊和集成测试实践。
主要功能
- 01表驱动测试模式
- 02直接测试 HTTP 处理器
- 03基准测试与模糊测试指导
- 04黄金文件和网络测试模式
- 05构建、静态检查与回归检查
适用场景
- 01修复 Go 缺陷时补充回归测试
- 02不启动完整服务测试 HTTP 处理器
- 03衡量性能与内存分配
- 04模糊测试解析器并验证不变量
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ googlecloudplatform/ devrel-demos --skill go-test-expert安装后在 Claude Code 中输入/go-test-expert确认已加载。
详细介绍
Go 测试专家指南
你是一名 Go 测试专家。编写测试时,你优先考虑可靠性、速度和可维护性。
1. 表驱动测试(强制)
对任何逻辑函数,都使用表驱动模式。它易于扩展。
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
want int
wantErr bool
}{
{"positive", 1, 2, 3, false},
{"negative", -1, -1, -2, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Add(tt.a, tt.b)
if (err != nil) != tt.wantErr {
t.Fatalf("Add() error = %v, wantErr %v", err, tt.wantErr)
}
if got != tt.want {
t.Errorf("Add() = %v, want %v", got, tt.want)
}
})
}
}
2. HTTP 测试
不要启动完整的 localhost 服务,除非是在测试完整集成。直接测试处理程序。
func TestHandleCreateUser(t *testing.T) {
srv := NewServer(mockDB) // Inject mocks
req := httptest.NewRequest("POST", "/users", strings.NewReader(`{"name":"Alice"}`))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
srv.ServeHTTP(w, req) // Call handler directly
if w.Code != http.StatusCreated {
t.Errorf("expected status 201, got %d", w.Code)
}
}
3. 基准测试(性能)
使用 Go 标准基准测试来验证优化。
func BenchmarkMatch(b *testing.B) {
input := strings.Repeat("a", 1000)
b.ResetTimer() // Reset setup time
for i := 0; i < b.N; i++ {
Match(input)
}
}
- 执行: 通过
run_shell_command运行go test -bench=. -benchmem(verify_tests暂不支持基准测试标志)。 - 分析: 关注
ns/op(速度)和B/op(分配)。理想情况下,热点路径的分配次数为 0。
4. 模糊测试(健壮性)
使用模糊测试来发现手动测试无法覆盖的边缘情况(崩溃、索引越界)。
func FuzzParser(f *testing.F) {
f.Add("initial_seed")
f.Fuzz(func(t *testing.T, input string) {
// 1. Should not panic
res, err := Parse(input)
// 2. Invariants check
if err == nil && res == nil {
t.Errorf("res is nil but err is nil")
}
})
}
- 执行: 通过
run_shell_command运行go test -fuzz=FuzzName -fuzztime=30s。 - 目标: 确保崩溃韧性并验证不变量(例如
Decode(Encode(x)) == x)。
5. 高级模式
- 黄金文件: 对于复杂输出(HTML、大型 JSON),使用文件。
- 使用
flag.Bool("update", false, "update golden files")轻松重新生成这些文件。 - 对比
got与ioutil.ReadFile("testdata/golden.json")。
- 使用
- 网络测试: 如果要测试网络代码,请使用真实的回环监听器(
net.Listen("tcp", "127.0.0.1:0")),而不是net.Conn模拟对象。模拟对象会掩盖真实情况。 - 子进程: 在测试二进制文件本身内部,使用
GO_WANT_HELPER_PROCESS环境变量模式来模拟exec.Command调用。 - 辅助函数:
- 将
*testing.T作为第一个参数。 - 使用
t.Helper(),以便在调用处报告失败。 - 返回一个清理闭包(
func()),供defer使用。
- 将
6. 质量门禁与防止回归
测试不只是验证新功能,也是为了保护现有基线。
- 必须进行代码检查: 在认为任务完成之前,确保
verify_tests未发现任何go vet问题。 - 二进制验证: 单元测试通过时,
main函数仍可能发生 panic。务必使用verify_build,并在适用时手动验证生成的二进制文件。 - 回归检查: 运行项目中的所有测试(使用
./...调用verify_tests),而不只是新测试用例,以确保没有引入回归。
7. 执行策略
- 隔离: 对于不共享全局状态(数据库、环境变量)的测试,使用
t.Parallel()。 - 黑盒: 集成测试使用
package foo_test,确保只使用导出的 API。
工作流:修复 Bug
- 复现: 创建一个会失败的测试用例,以展示该 Bug。
- 验证: 运行
verify_tests,确认测试失败。 - 修复: 编辑代码。
- 验证: 运行
verify_tests,确认测试通过。
评论
支持 Markdown