ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ECC 的 Go 测试规则:go test 表驱动测试、-race 竞态检测与 80% 覆盖率要求

ECC 的 Go 测试规则:go test 表驱动测试、-race 竞态检测与 80% 覆盖率要求 ECC 的 Go 测试规则go test 表驱动测试、-race 竞态检测与 80% 覆盖率要求【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC本文以 ECC 仓库中的 Go 测试规则文件 docs/es/rules/golang/testing.md 为核心完整解读 ECC 分层规则体系下 Go 语言的测试标准为什么坚持标准库go test与表驱动测试、-race竞态检测如何成为强制项、覆盖率要求从哪里来。读完本篇你将掌握在 ECC 框架内为 Go 项目落地 TDD 测试规范的全部要素——规则文件的生效机制、扩展自通用测试规则的继承关系、以及配套的golang-testing技能与/go-test命令提供的表驱动测试、子测试、基准测试与模糊测试等完整实践。规则文件的定位与生效机制ECC 采用「通用层common 语言专属层」的分层规则架构这一点在 rules/README.md 中有明确说明rules/common/存放与语言无关的通用原则各语言目录则「用框架特定的模式、工具和代码示例扩展通用规则每个文件都引用其对应的 common 文件」。Go 测试规则正是这一模式的实例。该文件英文原版为 rules/golang/testing.md西班牙语版即 docs/es/rules/golang/testing.md以 YAML frontmatter 声明了路径匹配范围paths: - **/*.go - **/go.mod - **/go.sum这表示规则仅在涉及.go源文件或go.mod/go.sum模块文件时被触发避免在无关项目中引入噪音。安装方面按 rules/README.md 的指引可通过./install.sh golang一键安装 Go 规则集或手动将rules/common与rules/golang目录复制到~/.claude/rules/ecc/用户级或项目根目录的.claude/rules/ecc/项目级。README 特别提醒必须整目录复制不能用/*压平——因为 common 与语言目录中存在同名文件压平会导致语言特定文件覆盖通用规则并破坏语言文件依赖的../common/相对引用。当语言特定规则与通用规则冲突时遵循「特定覆盖通用」的优先级原则类似 CSS 优先级或.gitignore的覆盖规则。规则核心go test 标准库与表驱动测试该规则文件的第一条核心声明是使用标准go test并采用表驱动测试table-driven tests。ECC 没有引入第三方测试框架而是把「用标准库 表驱动模式覆盖大量用例」定为 Go 项目的强制标准。表驱动测试是 Go 社区的标准范式用一个结构体切片描述多个用例再循环调用t.Run生成子测试既能用最少代码获得全面覆盖又能让每个用例在输出中拥有独立、可读的名字。配套的golang-testing技能skills/golang-testing/SKILL.md给出了规则要求的完整参考实现func TestAdd(t *testing.T) { tests : []struct { name string a, b int expected int }{ {positive numbers, 2, 3, 5}, {negative numbers, -1, -2, -3}, {zero values, 0, 0, 0}, {mixed signs, -1, 1, 0}, {large numbers, 1000000, 2000000, 3000000}, } for _, tt : range tests { t.Run(tt.name, func(t *testing.T) { got : Add(tt.a, tt.b) if got ! tt.expected { t.Errorf(Add(%d, %d) %d; want %d, tt.a, tt.b, got, tt.expected) } }) } }对于需要断言错误的解析类函数技能进一步给出带wantErr字段的扩展模式成功路径用t.Fatalf中断当前子测试避免后续空指针错误路径则先校验「确实产生了错误」就提前return成功路径再用reflect.DeepEqual比对期望值。子测试与并行执行技能文档还覆盖了组织相关测试的子测试模式——在父测试中共享 setup如setupTestDB(t)再以t.Run(Create/Get/Update/Delete, ...)组织 CRUD 用例以及并行子测试模式对独立用例调用t.Parallel()提升执行效率for _, tt : range tests { tt : tt // Capture range variable t.Run(tt.name, func(t *testing.T) { t.Parallel() result : Process(tt.input) }) }竞态检测-race 是强制项规则文件中明确写道「Siempre ejecutar con la flag-race」始终使用-race标志运行go test -race ./...这是 Go 并发场景下的关键防线。go test -race会启用官方竞态检测器ThreadSanitizer 衍生实现在测试运行时追踪共享内存的并发访问捕获未同步的数据竞争。由于竞态条件往往只在特定调度下暴露把它固化进每次测试运行比「上线后靠生产事故发现」可靠得多。技能文档的测试命令清单里go test -race ./...与go test -race -coverprofilecoverage.out ./...竞态检测与覆盖率叠加运行都列在常规命令之列与规则文件的要求一脉相承。覆盖率要求及其来源规则文件给出了最简覆盖率检查命令go test -cover ./...具体的覆盖率门槛则继承自它扩展的通用测试规则docs/es/rules/common/testing.md。该父文件规定了 ECC 的完整测试要求最低测试覆盖率80%三类测试全部必需单元测试函数、工具、组件、集成测试API 端点、数据库操作、E2E 测试关键用户流程框架按语言选择强制 TDD 工作流先写测试RED→ 运行确认失败 → 写最小实现GREEN→ 运行确认通过 → 重构IMPROVE→ 验证覆盖率80%测试失败排障顺序使用tdd-guide代理、检查测试隔离性、检查 mock 正确性、修实现而不是修测试除非测试本身写错AAA 结构与命名规范优先 Arrange-Act-Assert 三段式组织测试体测试名应描述被验证的行为如「当没有市场匹配查询时返回空数组」「缺少 API 密钥时抛出错误」「Redis 不可用时回退到子串搜索」。在 Go 侧覆盖率检查还可以进一步细化golang-testing技能提供了完整的命令集# Basic coverage go test -cover ./... # Generate coverage profile go test -coverprofilecoverage.out ./... # View coverage in browser go tool cover -htmlcoverage.out # View coverage by function go tool cover -funccoverage.out # Coverage with race detection go test -race -coverprofilecoverage.out ./...技能同时给出了按代码类型分级的覆盖率目标与通用规则的 80% 底线衔接代码类型目标关键业务逻辑100%公共 API90%一般代码80%生成代码排除规则与技能的分工golang-testing 技能的纵深实践ECC 在 rules/README.md 中定义了清晰的分工原则Rules 规定「做什么」Skills 讲解「怎么做」——规则文件给出标准与检查清单而 skills/golang-testing/SKILL.md 提供可操作的深度参考。规则文件末尾的「Referencia」一节正是指向这一技能的入口。技能中值得重点关注的几类实践如下。测试助手与资源清理助手函数用t.Helper()标记失败时报告调用方位置而非助手本身用t.Cleanup保证资源释放用t.TempDir()自动管理临时目录func setupTestDB(t *testing.T) *sql.DB { t.Helper() db, err : sql.Open(sqlite3, :memory:) if err ! nil { t.Fatalf(failed to open database: %v, err) } t.Cleanup(func() { db.Close() }) if _, err : db.Exec(schema); err ! nil { t.Fatalf(failed to create schema: %v, err) } return db } func assertEqualT comparable { t.Helper() if got ! want { t.Errorf(got %v; want %v, got, want) } }基于接口的 MockingGo 没有内置 mock 框架技能给出的惯用手法是「定义接口 函数字段 mock 结构体」生产实现与测试 mock 各自满足同一接口type UserRepository interface { GetUser(id string) (*User, error) SaveUser(user *User) error } type MockUserRepository struct { GetUserFunc func(id string) (*User, error) SaveUserFunc func(user *User) error } func (m *MockUserRepository) GetUser(id string) (*User, error) { return m.GetUserFunc(id) }基准测试与模糊测试基准测试用b.ResetTimer()排除 setup 开销并支持按数据规模分档比较size100/1000/10000/100000与内存分配对比-benchmemfunc BenchmarkProcess(b *testing.B) { data : generateTestData(1000) b.ResetTimer() // Dont count setup time for i : 0; i b.N; i { Process(data) } } // Run: go test -benchBenchmarkProcess -benchmem模糊测试Go 1.18先通过f.Add提供种子语料再声明「不变式」让引擎自动探索输入空间。例如对 JSON 解析器的属性「成功 Unmarshal 的结果必须能再次 Marshal」对比较函数的属性「Compare(a,a) 必须为 0且 Compare(a,b) 与 Compare(b,a) 符号相反」func FuzzParseJSON(f *testing.F) { f.Add({name: test}) f.Add({count: 123}) f.Add([]) f.Fuzz(func(t *testing.T, input string) { var result map[string]interface{} if err : json.Unmarshal([]byte(input), result); err ! nil { return // Invalid JSON is expected for random input } if _, err : json.Marshal(result); err ! nil { t.Errorf(Marshal failed after successful Unmarshal: %v, err) } }) } // Run: go test -fuzzFuzzParseJSON -fuzztime30s完整测试命令清单技能汇总的常用命令覆盖了规则文件两大要求race、coverage的所有组合形式并补充了单测定位、短时运行、超时控制与 flaky 检测go test ./... # 运行全部测试 go test -v ./... # 详细输出 go test -run TestAdd ./... # 运行指定测试 go test -run TestUser/Create ./... # 匹配子测试模式 go test -race ./... # 竞态检测 go test -cover -coverprofilecoverage.out ./...# 覆盖率 go test -short ./... # 仅短测试 go test -timeout 30s ./... # 超时控制 go test -bench. -benchmem ./... # 基准测试 go test -fuzzFuzzParse -fuzztime30s ./... # 模糊测试 go test -count10 ./... # 多次运行检测 flaky/go-test 命令TDD 流程的强制执行规则文件定义了「标准」而 commands/go-test.md 则把标准转化为可执行的 TDD 会话流程。该命令的说明是「为 Go 代码强制执行 TDD 工作流先写表驱动测试再实现并用go test -cover验证 80% 覆盖率」其步骤与通用测试规则中的六步工作流一一对应定义类型/接口 → 写表驱动测试RED→ 运行验证失败 → 最小实现GREEN→ 重构 → 检查覆盖率。该命令内置了一个完整的邮箱校验器 TDD 会话示例先用panic(not implemented)占位定义ValidateEmail再写覆盖 10 个用例简单邮箱、子域、加号标签、空串、缺 、无 TLD 等的表驱动测试确认go test报panic: not implemented后用正则^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$实现最小逻辑最终go test -cover输出coverage: 100.0% of statements。这展示了规则文件中「table-driven -cover」两条要求在一个真实功能开发中如何闭环。命令文档同时列出了最佳实践边界应该做——先写测试、用表驱动、测行为不测实现、包含边界用例空、nil、最大值不要做——先写实现再补测试、跳过 RED 阶段、直接测私有函数、在测试里用time.Sleep、放任 flaky 测试。CI 集成把规则变成流水线门槛golang-testing技能末尾给出了 CI/CD 集成示例将-race与覆盖率门槛固化为流水线步骤这正是规则文件两条核心要求在持续集成中的落地形态test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-gov5 with: go-version: 1.22 - name: Run tests run: go test -race -coverprofilecoverage.out ./... - name: Check coverage run: | go tool cover -funccoverage.out | grep total | awk {print $3} | \ awk -F% {if ($1 80) exit 1}覆盖率不足 80% 时该步骤以非零退出码失败使通用测试规则中的「80%」底线在 CI 中可机器校验。小结从规则到实践的完整链路ECC 中 Go 测试标准可以归纳为一条链路规则文件docs/es/rules/golang/testing.md / rules/golang/testing.md通过 frontmatter 路径匹配决定何时生效声明go test表驱动、-race常开、-cover检查三条硬性标准向上扩展自 docs/es/rules/common/testing.md 继承 80% 覆盖率底线、TDD 六步流程与 AAA 结构向下由 skills/golang-testing/SKILL.md 提供子测试、助手函数、接口 mock、黄金文件、基准与模糊测试的具体实现范式再由 commands/go-test.md 以/go-test命令驱动 TDD 会话落地执行。这套「规则定标准、技能给方法、命令跑流程」的三层设计是 ECC 作为 Agent 性能优化框架在 Go 项目上保证测试质量的核心机制。相关文件索引文件作用docs/es/rules/golang/testing.md本文核心Go 测试规则西班牙语版rules/golang/testing.md同一规则的英文原版docs/es/rules/common/testing.md被扩展的通用测试规则80% 覆盖率、TDD 流程rules/README.md规则分层架构、安装方式与优先级说明skills/golang-testing/SKILL.md表驱动、基准、模糊测试等完整模式参考commands/go-test.md/go-testTDD 命令定义与会话示例【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进