# Tdd

> 使用红绿重构循环进行测试驱动开发。当用户想要使用 TDD 构建特性或修复错误、提到"红绿重构"、想要集成测试，或要求测试优先开发时使用。

- Skill: `karasukaigan/tdd` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add karasukaigan/tdd`
- Raw SKILL.md: https://api.skillmd.com/api/skills/karasukaigan/tdd/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: karasukaigan (https://skillmd.com/u/karasukaigan)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/karasukaigan/tdd

---


# 测试驱动开发

## 哲学

**核心原则**：测试应该通过公共接口验证行为，而不是实现细节。代码可以完全改变；测试不应该。

**好的测试**是集成风格的：它们通过公共 API 练习真实的代码路径。它们描述系统_做什么_，而不是_如何_做它。一个好的测试读起来像规范——"用户可以使用有效购物车结账"告诉你确切存在什么能力。这些测试在重构中存活，因为它们不关心内部结构。

**坏的测试**耦合到实现。它们模拟内部协作者、测试私有方法，或通过外部手段验证（如直接查询数据库而不是使用接口）。警告信号：当你重构时测试失败，但行为没有改变。如果你重命名内部函数而测试失败，那些测试正在测试实现，而不是行为。

参见 [tests.md](tests.md) 获取示例，[mocking.md](mocking.md) 获取模拟指南。

## 反模式：水平切片

**不要先编写所有测试，然后编写所有实现。** 这是"水平切片"——将 RED 视为"编写所有测试"，将 GREEN 视为"编写所有代码"。

这会产生**糟糕的测试**：

- 批量编写的测试测试_想象的_行为，而不是_实际的_行为
- 你最终测试事物的_形状_（数据结构、函数签名）而不是面向用户的行为
- 测试对真实变化不敏感——当行为破坏时它们通过，当行为正常时它们失败
- 你跑过了车头灯，在理解实现之前就承诺了测试结构

**正确的方法**：通过示踪弹进行垂直切片。一个测试 → 一个实现 → 重复。每个测试响应你从上一个周期学到的内容。因为你刚刚编写了代码，你确切知道什么行为重要以及如何验证它。

```
错误（水平）：
  RED:   test1, test2, test3, test4, test5
  GREEN: impl1, impl2, impl3, impl4, impl5

正确（垂直）：
  RED→GREEN: test1→impl1
  RED→GREEN: test2→impl2
  RED→GREEN: test3→impl3
  ...
```

## 工作流

### 1. 规划

在探索代码库时，使用项目的领域词汇表，以便测试名称和接口语汇与项目的语言匹配，并尊重你正在接触的区域中的 ADR。

在编写任何代码之前：

- [ ] 与用户确认需要哪些接口变更
- [ ] 与用户确认要测试哪些行为（优先）
- [ ] 识别 [深层模块](deep-modules.md) 的机会（小接口，深实现）
- [ ] 为 [可测试性](interface-design.md) 设计接口
- [ ] 列出要测试的行为（不是实现步骤）
- [ ] 获得用户对计划的批准

问："公共接口应该是什么样子？哪些行为最重要需要测试？"

**你不能测试所有内容。** 与用户确认确切哪些行为最重要。将测试精力集中在关键路径和复杂逻辑上，而不是每个可能的边缘情况。

### 2. 示踪弹

编写一个测试来确认关于系统的_一件事_：

```
RED:   为第一个行为编写测试 → 测试失败
GREEN: 编写最小代码以通过 → 测试通过
```

这是你的示踪弹——证明端到端的路径有效。

### 3. 增量循环

对于每个剩余的行为：

```
RED:   编写下一个测试 → 失败
GREEN: 最小代码以通过 → 通过
```

规则：

- 一次一个测试
- 仅足够的代码来通过当前测试
- 不要预测未来的测试
- 保持测试专注于可观察的行为

### 4. 重构

在所有测试通过后，寻找 [重构候选](refactoring.md)：

- [ ] 提取重复
- [ ] 深化模块（将复杂性移到简单接口后面）
- [ ] 在自然的地方应用 SOLID 原则
- [ ] 考虑新代码揭示了关于现有代码的什么
- [ ] 在每个重构步骤后运行测试

**在 RED 时永远不要重构。** 先到 GREEN。

## 每个周期的检查清单

```
[ ] 测试描述行为，而不是实现
[ ] 测试仅使用公共接口
[ ] 测试会在内部重构中存活
[ ] 代码对此测试是最小的
[ ] 没有添加推测性功能
```
