plugins/languages/golang/skills/testing/SKILL.md
Go 测试规范——表驱动测试(t.Run 子测试)、testing/synctest 确定性并发测试(Go 1.25 GA)、模糊测试(go test -fuzz)、基准测试(B.Loop, Go 1.24+)、testify 断言、mock 全局 state、覆盖率 ≥90%。写单元测试/集成测试/benchmark、调查 flaky 测试、设计 mock 策略时触发。
npx skillsauth add lazygophers/ccplugin golang-testingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
_test.go,函数命名 TestXxx/BenchmarkXxx/FuzzXxx。t.Run 子测试。time.Sleep 等待异步,并发测试用 testing/synctest(Go 1.25 GA)。t.Parallel() 默认开。func TestUserLogin(t *testing.T) {
tests := []struct {
name string
username string
password string
wantErr bool
}{
{"valid", "user", "pass123", false},
{"wrong password", "user", "wrong", true},
{"empty user", "", "pass123", true},
{"empty pass", "user", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
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")
}
})
}
}
注:Go 1.22+ 循环变量每轮新建,无需 tt := tt。
杀手锏:测试涉及 time.After/context.WithTimeout/goroutine 协作时,告别 time.Sleep 和 flaky 测试。
import "testing/synctest"
func TestContextDeadline(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
synctest.Wait() // 等所有 goroutine durably blocked
select {
case <-ctx.Done():
// ctx 已超时(假时钟瞬间推进)
default:
t.Fatal("ctx should be done")
}
})
}
time 用假时钟,零等待。synctest.Wait() 阻塞到 bubble 内所有 goroutine durably blocked。func FuzzParseJSON(f *testing.F) {
f.Add(`{"name":"test"}`)
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/
解析器、编解码器、URL 处理类强制写 fuzz。
func BenchmarkProcessData(b *testing.B) {
data := generateTestData(1000)
b.ReportAllocs()
for b.Loop() { // Go 1.24+,自动 ResetTimer + 避免编译器消除
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 TestCreate(t *testing.T) {
user, err := CreateUser("[email protected]")
require.NoError(t, err) // 失败即停
require.NotNil(t, user)
assert.Equal(t, "[email protected]", user.Email)
}
require 用于必要前提,失败即停;assert 用于次要断言,可累积。
func TestUserLoginWithMock(t *testing.T) {
orig := state.User
defer func() { state.User = orig }()
state.User = &MockUserModel{
users: map[int64]*User{1: {Id: 1, Email: "[email protected]"}},
}
user, err := UserLogin("[email protected]", "pwd")
require.NoError(t, err)
assert.Equal(t, "[email protected]", user.Email)
}
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out | grep total
go tool cover -html=coverage.out
go test -v -race -cover ./...
CI 中用 vladopajic/go-test-coverage 配置 .testcoverage.yml 设阈值。
| AI 借口 | 实际应验证 | | --- | --- | | "80% 覆盖率够了" | ≥90%,关键路径 100%? | | "fuzz 太慢" | 解析器/编解码器有 fuzz? | | "time.Sleep 等等" | 用 testing/synctest? | | "mock 一切" | 仅 mock 外部依赖? | | "Test1/Test2" | 子测试 name 描述性? | | "跳过错误路径" | 错误路径有用例? |
_test.go、函数 Test/Benchmark/Fuzz 前缀t.Runt.Parallel() 开启testing/synctest-racetesting/synctest 官博 — https://go.dev/blog/synctesttools
UI/UX 与布局设计——做界面布局/结构/导航/组件/交互的设计决策。触发:做UI/UX/布局/排版/导航/组件/交互/栅格/响应式/图表选型/字体配对。按媒介路由 HTML/Web、原生 App(iOS/Android/桌面)、CLI、TUI。需后端动态系统不适用;配色/主题/色板走姊妹 skill design-color。
tools
主题与配色设计——做颜色搭配/调色板/主题/品牌色阶/暗模式的设计决策。触发:选配色/调色/主题/色板/品牌色/暗模式/对比度/色盲/UI风格。按媒介路由 HTML/Web(CSS变量)、原生App(平台token)、CLI(ANSI)、TUI(真彩/256/16降级)。保证可访问性(对比度/色盲安全)。需后端动态系统不适用;UI/UX 布局/组件/交互走姊妹 skill design-uiux。
tools
跨任意组件(plugin/skill/agent/command)的验证驱动优化循环纪律 skill。当用户要优化某个已有组件却无明确方向、或要防止改了反而更差(自评乐观偏差 / 多维同改归因失效 / 为凑分加废话膨胀)、或要把一套通用「评分→单变量改→改后验证严格更好才留否则回滚→触顶停」的纪律套到任意组件上时使用。管优化过程本身的纪律(validation gate / ratchet / 独立验证 / 触顶停),不评单组件深度(交 skill-dev),不查插件接线(交 plugin-dev)。仅手动 /optimize-any 触发。
data-ai
两层规则记忆 (基于 .skein/spec)。planning 时 recall 召回相关规则、task finish 后 sediment 沉淀学习 + prune 自动精简过期/重复/断链规则。core 常驻硬规 + recall 按需召回, 经判定门自动写盘 (不逐次问用户)。产出 .skein/spec 下 core/recall 规则文件 + index。另支持空仓 bootstrap 播种规则基线、记忆大面积失效 (大重构/换栈) 时 reconstruct 可逆归档后按项目类型分型重建、maintain 手动体检 (超预算/stale/断链/重复/废弃, --apply 自动修复)、auto-fix (Stop hook 写 .pending-fix 标记 → main 派 skein-specer bg 跑 maintain --apply 全自动修, 断链只报告)。