writing-tests
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWriting 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模型
| Priority | Type | When |
|---|---|---|
| 1st | Integration | Default - multiple units with real dependencies |
| 2nd | E2E | Complete user workflows |
| 3rd | Unit | Pure 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
断言策略
| Context | Assert On | Avoid |
|---|---|---|
| UI | Visible text, roles | CSS classes, internal state |
| API | Response body, status | Internal DB state |
| Library | Return values | Private methods |
| 场景 | 应断言的内容 | 应避免的内容 |
|---|---|---|
| UI层 | 可见文本、角色(roles) | CSS类、内部状态 |
| API层 | 响应体、状态码 | 数据库内部状态 |
| 类库 | 返回值 | 私有方法 |
Anti-Patterns
反模式
| Pattern | Fix |
|---|---|
| Testing mock calls | Test actual outcome |
| Test-only methods in production | Move to test utilities |
| Use condition-based waiting |
| Asserting on internal state | Assert on observable output |
| Incomplete mocks | Mirror real API completely |
| 反模式 | 修复方案 |
|---|---|
| 测试模拟对象的调用情况 | 测试实际输出结果 |
| 生产代码中包含仅用于测试的方法 | 移至测试工具类中 |
| 使用基于条件的等待 |
| 断言内部状态 | 断言可观察的输出 |
| 不完整的模拟对象 | 完全镜像真实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)记住: 优先行为而非实现,优先真实而非模拟,优先输出而非内部细节。