From golang
Go 测试编写规范:表驱动测试(table-driven)、子测试(t.Run)、模糊测试(go test -fuzz)、基准测试(benchmark/benchstat)、testify 断言与 mock、覆盖率 >= 90%、测试辅助函数。适用于编写单元测试、集成测试、性能基准场景。
npx claudepluginhub lazygophers/ccplugin --plugin golangThis skill uses the workspace's default tool permissions.
- **dev** - 开发专家
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides MCP server integration in Claude Code plugins via .mcp.json or plugin.json configs for stdio, SSE, HTTP types, enabling external services as tools.
| 场景 | Skill | 说明 |
|---|---|---|
| 核心规范 | Skills(golang:core) | 核心规范:强制约定 |
| 错误处理 | Skills(golang:error) | 错误路径测试 |
| 并发测试 | Skills(golang:concurrency) | race 检测、并发测试 |
| 工具链 | Skills(golang:tooling) | go test 命令、pprof |
_test.go 结尾Test 开头func TestUserLogin(t *testing.T) {
tests := []struct {
name string
username string
password string
wantErr bool
}{
{"valid login", "testuser", "password123", false},
{"invalid password", "testuser", "wrong", true},
{"empty username", "", "password123", true},
{"empty password", "testuser", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
user, err := UserLogin(tt.username, tt.password)
if (err != nil) != tt.wantErr {
t.Errorf("UserLogin() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && user == nil {
t.Error("UserLogin() returned nil user")
}
})
}
}
func FuzzParseJSON(f *testing.F) {
// 种子语料
f.Add(`{"name":"test"}`)
f.Add(`{}`)
f.Add(`[]`)
f.Add(`""`)
f.Fuzz(func(t *testing.T, input string) {
result, err := ParseJSON(input)
if err != nil {
return // 合法的解析失败
}
// 验证不变量
if result == nil {
t.Error("ParseJSON returned nil without error")
}
})
}
运行模糊测试:
go test -fuzz=FuzzParseJSON -fuzztime=30s ./parser/
func BenchmarkProcessData(b *testing.B) {
data := generateTestData(1000)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
ProcessData(data)
}
}
基准对比:
go test -bench=. -benchmem -count=5 > old.txt
# 修改代码后
go test -bench=. -benchmem -count=5 > new.txt
benchstat old.txt new.txt
import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCalculate(t *testing.T) {
result := Calculate(2, 3)
assert.Equal(t, 5, result)
assert.NotZero(t, result)
}
func TestCreateUser(t *testing.T) {
user, err := CreateUser("test@example.com")
require.NoError(t, err) // 失败则立即终止
require.NotNil(t, user)
assert.Equal(t, "test@example.com", user.Email)
}
func TestUserLoginWithMock(t *testing.T) {
originalUser := state.User
defer func() { state.User = originalUser }()
state.User = &MockUserModel{
users: map[int64]*User{
1: {Id: 1, Email: "test@example.com"},
},
}
user, err := UserLogin("test@example.com", "password")
require.NoError(t, err)
assert.Equal(t, "test@example.com", user.Email)
}
# 运行并生成覆盖率
go test -coverprofile=coverage.out ./...
# 查看总覆盖率
go tool cover -func=coverage.out | grep total
# HTML 报告
go tool cover -html=coverage.out
# 带 race 检测
go test -v -race -cover ./...
| AI 可能的理性化解释 | 实际应该检查的内容 | 严重程度 |
|---|---|---|
| "80% 覆盖率就够了" | 是否 >= 90%,关键路径 100%? | 高 |
| "不需要 fuzz 测试" | 解析器/编解码器是否有 fuzz? | 中 |
| "time.Sleep 等等就好" | 是否用确定性同步机制? | 高 |
| "mock 一切依赖" | 是否只 mock 外部依赖? | 中 |
| "Test1/Test2 命名" | 表驱动测试 name 是否有描述性? | 中 |
| "跳过错误路径" | 错误路径是否有测试? | 高 |
_test.go 结尾Test 开头