用途
测试驱动开发(TDD)是一种以测试为先的软件开发方法。其核心原则是:先写测试,看着它失败,再写最小代码使其通过。如果没亲眼看到测试失败,就无法确定它测试的是正确的东西。违反规则的文字就是违反规则的精神。
主要能力
该技能定义了 TDD 的完整工作循环与纪律:
- 铁律:没有失败的测试,就不写生产代码。如果先写了代码,必须删除并重新开始,不能保留作“参考”、不能在写测试时“改编”、不能看它。删除就是删除。
- 红-绿-重构循环:
- RED:编写一个最小的失败测试,展示应该发生什么。要求:一个行为、清晰的名称、真实代码(除非不可避免,否则不用 mock)。
- 验证 RED:强制步骤,运行测试并确认它失败(不是报错)、失败信息符合预期、失败原因是功能缺失(不是拼写错误)。如果测试通过,说明你在测试已有行为,需要修正测试;如果测试报错,先修复错误直到它正确失败。
- GREEN:编写最简单的代码使测试通过。不要添加功能、重构其他代码或超出测试范围“改进”。
- 验证 GREEN:强制步骤,确认测试通过、其他测试仍然通过、输出干净(无错误、警告)。如果测试失败,修代码而不是改测试;如果其他测试失败,立即修复。
- REFACTOR:仅在绿灯后进行。消除重复、改进命名、提取辅助函数。保持测试绿灯,不添加行为。
- 重复:为下一个功能编写下一个失败测试。
使用方式
该技能适用于所有新功能、缺陷修复、重构和行为变更。例外情况(需询问人类伙伴):一次性原型、生成的代码、配置文件。
具体操作步骤:
- 编写一个最小测试,展示期望行为。
- 运行测试,确认它因预期原因失败。
- 编写最小代码使测试通过。
- 运行测试,确认通过且其他测试不受影响。
- 在绿灯下重构,保持测试通过。
- 重复上述循环。
该技能还提供了验证清单,在标记工作完成前需逐项检查:每个新函数/方法都有测试;在实现前亲眼看到每个测试失败;每个测试因预期原因失败(功能缺失,而非拼写错误);为每个测试编写了最小代码;所有测试通过;输出干净(无错误、警告);测试使用真实代码(仅在不可避免时使用 mock);覆盖边界情况和错误。如果无法勾选所有项,说明跳过了 TDD,需要重新开始。
适用场景
- 新功能开发
- 缺陷修复(先写复现缺陷的失败测试,遵循 TDD 循环,测试证明修复并防止回归)
- 重构
- 行为变更
限制
该技能明确列出了一些例外情况,但需要询问人类伙伴:一次性原型、生成的代码、配置文件。此外,该技能强调不能以“太简单不用测试”“稍后再测”“已经手动测试过”“删除 X 小时工作太浪费”“TDD 太教条,我要务实”“测试后写也能达到同样目标”等理由跳过 TDD。这些借口在技能中都有对应的现实反驳。
当遇到困难时,技能建议:不知道如何测试时,写出期望的 API、先写断言、询问人类伙伴;测试太复杂说明设计太复杂,简化接口;必须 mock 一切说明代码耦合太紧,使用依赖注入;测试设置庞大时提取辅助函数,仍然复杂则简化设计。
最终规则:生产代码必须有先失败的测试,否则就不是 TDD。未经人类伙伴许可,没有例外。