golang-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Workflow

Workflow

  1. 写测试函数 schema:参照 reference/schema.yaml 定义,要求严格符合 schema 标准
  2. 与用户确认 schema:按用户需求进行修改,直到用户满意再进行代码编写
  3. 最小实现:先做 1 个 happy path + 1 个关键失败 case,保证可重复。
  4. 交付可跑:给出
    go test ...
    指令与环境说明,用户手动执行回传结果。
  5. 扩展用例:边界 → 异常 → 并发/
    -race
    → 回归(修 bug 必补)。
  6. 收尾:更新 Schema(已实现/未实现原因)+ 最终运行说明(含可选参数)。
  1. Write test function schema: Refer to the definition in reference/schema.yaml, and strictly comply with the schema standard
  2. Confirm schema with users: Modify according to user requirements, and start coding only after users are satisfied
  3. Minimum implementation: First implement 1 happy path + 1 critical failure case to ensure repeatability.
  4. Deliver runnable content: Provide
    go test ...
    command and environment description, users execute manually and return results.
  5. Expand test cases: Boundary → Exception → Concurrency/
    -race
    → Regression (must be supplemented when fixing bugs).
  6. 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

  1. 按主题/行为分组,每组一个 Function
  2. 每个 function 分组内,对于不同的断言结构,使用 t.Run 子测试分开
  3. 每个子测试内使用同一断言结构,用 table-driven 覆盖更多的输入和边界 case
  4. 采用 AAA(Arrange-Act-Assert)或者 Given-When-Then 的结构分段,降低阅读成本
  5. 测试中避免“连环 if/复杂逻辑”,复杂准备过程抽出到 helper
  1. Group by topic/behavior, one Function per group
  2. Within each function group, use t.Run subtests to separate different assertion structures
  3. Use the same assertion structure within each subtest, and use table-driven to cover more inputs and boundary cases
  4. Adopt AAA (Arrange-Act-Assert) or Given-When-Then structure for segmentation to reduce reading cost
  5. Avoid "serial if/complex logic" in tests, extract complex preparation processes into helper functions

Techniques

Techniques

  1. 对于辅助函数,标记
    t.Helper()
    ,并对错误采用 FailFast 策略
  2. 对复杂的输出判断使用 golden file ,并提供更新开关
  3. mock
    1. mock interface 时,用纯 func 来实现接口,可以更方便的 mock 出不同的结果
    2. mock 特别复杂的 interface 时,使用 struct embedding 该接口,然后 override 要 mock 的 method
    3. mock 时要验证关键的交互
  1. For auxiliary functions, mark
    t.Helper()
    , and adopt FailFast strategy for errors
  2. Use golden file for complex output judgment, and provide an update switch
  3. mock
    1. When mocking an interface, use pure func to implement the interface, which can more conveniently mock different results
    2. When mocking a particularly complex interface, use struct embedding of the interface, and then override the method to be mocked
    3. 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)
  • 不要在测试里用
    time.Sleep()
    :用 channel、条件等待、可控时钟(Clock/now 注入)替代。
  • 不要 flaky
  • Do not directly test private functions (test through public API)
  • Do not use
    time.Sleep()
    in tests: Replace with channel, conditional wait, controllable clock (Clock/now injection).
  • Avoid flaky tests