golang-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWorkflow
Workflow
- 写测试函数 schema:参照 reference/schema.yaml 定义,要求严格符合 schema 标准
- 与用户确认 schema:按用户需求进行修改,直到用户满意再进行代码编写
- 最小实现:先做 1 个 happy path + 1 个关键失败 case,保证可重复。
- 交付可跑:给出 指令与环境说明,用户手动执行回传结果。
go test ... - 扩展用例:边界 → 异常 → 并发/→ 回归(修 bug 必补)。
-race - 收尾:更新 Schema(已实现/未实现原因)+ 最终运行说明(含可选参数)。
- Write test function schema: Refer to the definition in reference/schema.yaml, and strictly comply with the schema standard
- Confirm schema with users: Modify according to user requirements, and start coding only after users are satisfied
- Minimum implementation: First implement 1 happy path + 1 critical failure case to ensure repeatability.
- Deliver runnable content: Provide command and environment description, users execute manually and return results.
go test ... - Expand test cases: Boundary → Exception → Concurrency/→ Regression (must be supplemented when fixing bugs).
-race - Finalization: Update Schema (reasons for implemented/unimplemented items) + final operation instructions (including optional parameters).
Best Practice
Best Practice
Principles
Principles
- Test behavior, not implementation:优先验证对外可观察行为(返回值/错误/副作用/外部交互),避免绑定内部细节与重构成本
- 可重复、稳定、可维护:测试应在任意机器/任意时间运行结果一致;失败信息能快速定位问题
- 分层测试:用 unit 保证逻辑正确与高覆盖(快、稳定、隔离依赖),用 integration 保证关键链路正确(真实/近真实依赖,减少对 mock 的依赖),用 e2e 保证核心用户路径可用(隔离环境、少而精、强可观测)
- mock 时隔离外部依赖:对 DB/HTTP/时间/随机/文件系统等边界依赖,通过接口与依赖注入控制测试环境
- Test behavior, not implementation: Prioritize verification of externally observable behaviors (return values/errors/side effects/external interactions), avoid binding internal details and increasing refactoring costs
- Repeatable, stable, maintainable: Tests should produce consistent results on any machine at any time; failure information can quickly locate problems
- Layered testing: Use unit tests to ensure correct logic and high coverage (fast, stable, isolated dependencies), use integration tests to ensure correct key links (real/near-real dependencies, reduce reliance on mock), use e2e tests to ensure core user paths are available (isolated environment, small and precise, strong observability)
- Isolate external dependencies when mocking: For boundary dependencies such as DB/HTTP/time/random/file system, control the test environment through interfaces and dependency injection
Structure
Structure
- 按主题/行为分组,每组一个 Function
- 每个 function 分组内,对于不同的断言结构,使用 t.Run 子测试分开
- 每个子测试内使用同一断言结构,用 table-driven 覆盖更多的输入和边界 case
- 采用 AAA(Arrange-Act-Assert)或者 Given-When-Then 的结构分段,降低阅读成本
- 测试中避免“连环 if/复杂逻辑”,复杂准备过程抽出到 helper
- Group by topic/behavior, one Function per group
- Within each function group, use t.Run subtests to separate different assertion structures
- Use the same assertion structure within each subtest, and use table-driven to cover more inputs and boundary cases
- Adopt AAA (Arrange-Act-Assert) or Given-When-Then structure for segmentation to reduce reading cost
- Avoid "serial if/complex logic" in tests, extract complex preparation processes into helper functions
Techniques
Techniques
- 对于辅助函数,标记 ,并对错误采用 FailFast 策略
t.Helper() - 对复杂的输出判断使用 golden file ,并提供更新开关
- mock
- mock interface 时,用纯 func 来实现接口,可以更方便的 mock 出不同的结果
- mock 特别复杂的 interface 时,使用 struct embedding 该接口,然后 override 要 mock 的 method
- mock 时要验证关键的交互
- For auxiliary functions, mark , and adopt FailFast strategy for errors
t.Helper() - Use golden file for complex output judgment, and provide an update switch
- mock
- When mocking an interface, use pure func to implement the interface, which can more conveniently mock different results
- When mocking a particularly complex interface, use struct embedding of the interface, and then override the method to be mocked
- Verify key interactions when mocking
Must Do
Must Do
- 涉及并发一定要加 race
- 覆盖错误路径和关键边界
- 测试要可重复
- 测试失败信息要清晰,便于理解和定位
- Add race flag when concurrency is involved
- Cover error paths and critical boundaries
- Tests must be repeatable
- Test failure information must be clear, easy to understand and locate
Don't
Don't
- 不要直接测试 private functions, (test through public API)
- 不要在测试里用 :用 channel、条件等待、可控时钟(Clock/now 注入)替代。
time.Sleep() - 不要 flaky
- Do not directly test private functions (test through public API)
- Do not use in tests: Replace with channel, conditional wait, controllable clock (Clock/now injection).
time.Sleep() - Avoid flaky tests