writing-tests

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Writing Tests

编写测试

Core principle: Test user-observable behavior with real dependencies. Tests should survive refactoring.
"The more your tests resemble the way your software is used, the more confidence they can give you." — Kent C. Dodds
Why this matters: Tests exist to give you confidence. The Testing Trophy prioritizes integration tests because they test real behavior across real modules — giving maximum confidence per test written. Unit tests in isolation often just test mocks, not your actual system.
核心原则: 使用真实依赖项测试用户可观察的行为。测试应能在重构后依然有效。
“你的测试越贴近软件的实际使用方式,就能给你带来越高的信心。”——Kent C. Dodds
重要性: 测试的存在是为了给你信心。Testing Trophy模型优先考虑集成测试,因为它们测试的是跨真实模块的真实行为——每编写一个测试就能带来最大的信心。孤立的单元测试往往只是测试模拟对象,而非实际系统。

Testing Trophy Model

Testing Trophy模型

PriorityTypeWhen
1stIntegrationDefault - multiple units with real dependencies
2ndE2EComplete user workflows
3rdUnitPure functions only (no dependencies)
优先级测试类型适用场景
第一级集成测试默认选择 - 多单元+真实依赖项
第二级E2E测试完整用户工作流
第三级单元测试仅纯函数(无依赖项)

Mocking Guidelines

模拟(Mocking)指南

Default: Don't mock. Use real dependencies.
Only mock:
  • External HTTP/API calls
  • Time/randomness
  • Third-party services (payments, email)
Never mock:
  • Internal modules
  • Database queries (use test DB)
  • Business logic
  • Your own code calling your own code
Before mocking, ask: "What side effects does this have? Does my test need those?" If unsure, run with real implementation first, then add minimal mocking only where needed.
默认规则:不要使用模拟,使用真实依赖项。
仅在以下场景使用模拟:
  • 外部HTTP/API调用
  • 时间/随机数相关逻辑
  • 第三方服务(支付、邮件)
绝对不要模拟:
  • 内部模块
  • 数据库查询(使用测试数据库)
  • 业务逻辑
  • 自身代码调用自身代码
模拟前先问自己:“这会产生什么副作用?我的测试需要这些副作用吗?”如果不确定,先使用真实实现运行测试,仅在必要时添加最少的模拟。

Test Type Decision

测试类型决策

Complete user workflow? → E2E test
Pure function (no side effects)? → Unit test
Everything else → Integration test
是否是完整用户工作流?→ E2E测试
是否是纯函数(无副作用)?→ 单元测试
其他所有情况 → 集成测试

Assertion Strategy

断言策略

ContextAssert OnAvoid
UIVisible text, rolesCSS classes, internal state
APIResponse body, statusInternal DB state
LibraryReturn valuesPrivate methods
场景应断言的内容应避免的内容
UI层可见文本、角色(roles)CSS类、内部状态
API层响应体、状态码数据库内部状态
类库返回值私有方法

Anti-Patterns

反模式

PatternFix
Testing mock callsTest actual outcome
Test-only methods in productionMove to test utilities
sleep(500)
Use condition-based waiting
Asserting on internal stateAssert on observable output
Incomplete mocksMirror real API completely
反模式修复方案
测试模拟对象的调用情况测试实际输出结果
生产代码中包含仅用于测试的方法移至测试工具类中
sleep(500)
使用基于条件的等待
断言内部状态断言可观察的输出
不完整的模拟对象完全镜像真实API的行为

Quality Checklist

质量检查清单

  • Happy path covered
  • Error conditions handled
  • Real dependencies used (minimal mocking)
  • Tests survive refactoring
  • Test names describe behavior
  • 覆盖正常流程
  • 处理错误场景
  • 使用真实依赖项(最少模拟)
  • 测试在重构后依然有效
  • 测试名称描述行为

Language-Specific Patterns

语言特定模式

  • JavaScript/Typescript/React: See references/typescript-react.md
  • Python: See references/python.md
  • Go: See references/go.md
For flaky tests with timing issues, use
Skill(ce:condition-based-waiting)
.

Remember: Behavior over implementation. Real over mocked. Outputs over internals.
  • JavaScript/Typescript/React: 参考references/typescript-react.md
  • Python: 参考references/python.md
  • Go: 参考references/go.md
对于存在时序问题的不稳定测试,使用
Skill(ce:condition-based-waiting)

记住: 优先行为而非实现,优先真实而非模拟,优先输出而非内部细节。