关于 test-driven-development
test-driven-development 是面向软件开发者的测试驱动开发技能,指导先针对公共接口编写行为测试,再逐步实现并重构。其流程以单个测试与实现交替推进,避免一次写完所有测试或代码。
主要功能
- 01通过公共接口验证行为
- 02按单个测试逐步推进红绿循环
- 03优先编写集成式测试
- 04要求先确认接口与测试计划
- 05测试通过后再进行重构
适用场景
- 01为新功能规划重要行为测试
- 02逐项实现功能并验证测试
- 03检查测试是否依赖内部实现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ christopher-buss/ skills --skill test-driven-development安装后在 Claude Code 中输入/test-driven-development确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/deep-modules.mdinterface-design.mdmocking.mdrefactoring.mdtests.md详细介绍
测试驱动开发
理念
核心原则:测试应通过公共接口验证行为,而非实现细节。代码可以彻底改变;测试不应如此。
好的测试采用集成测试风格:通过公共 API 执行真实代码路径。它们描述系统_做什么_,而不是_如何做_。好的测试读起来就像一份规范——“用户可以使用有效购物车结账”清楚地说明了系统具备什么能力。这类测试经得起重构,因为它们不关心内部结构。
糟糕的测试与实现耦合。它们模拟内部协作者、测试私有方法,或通过外部手段验证(例如直接查询数据库,而不是使用接口)。一个警示信号是:重构时测试失败,但行为并未改变。如果你重命名一个内部函数后测试失败,那么这些测试测的是实现,而不是行为。
示例请参阅 tests.md,模拟指南请参阅 mocking.md。
反模式:水平切片
**不要先写完所有测试,再写完所有实现。**这就是“水平切片”——把 RED 当作“编写所有测试”,把 GREEN 当作“编写所有代码”。
这样会产生糟糕的测试:
- 批量编写的测试测的是_想象中的_行为,而非_实际的_行为
- 你最终测的是事物的_形状_(数据结构、函数签名),而非面向用户的行为
- 测试会对真实变化不敏感——行为出错时仍然通过,行为正常时反而失败
- 你会超前于实际进展,在理解实现之前就确定测试结构
正确方法:通过示踪弹进行垂直切片。一个测试 → 一个实现 → 重复。每个测试都回应你从上一个周期中学到的内容。因为你刚刚编写了代码,所以清楚哪些行为重要,以及如何验证它们。
WRONG (horizontal):
RED: test1, test2, test3, test4, test5
GREEN: impl1, impl2, impl3, impl4, impl5
RIGHT (vertical):
RED→GREEN: test1→impl1
RED→GREEN: test2→impl2
RED→GREEN: test3→impl3
...
工作流
1. 规划
编写任何代码之前:
询问:“公共接口应该是什么样?哪些行为最值得优先测试?”
**你无法测试所有内容。**与用户准确确认哪些行为最重要。将测试精力集中在关键路径和复杂逻辑上,而不是所有可能的边缘情况。
使用 test.todo 为测试文件编写测试描述存根(不含实现),以便在编写任何代码之前获取用户对覆盖范围的反馈。
2. 示踪弹
编写一个测试,确认系统的一项行为:
RED: Write test for first behavior → test fails
GREEN: Write minimal code to pass → test passes
COMMIT: Commit this working test and code
这是你的示踪弹,用于证明整个端到端路径有效。
3. 增量循环
对于每项剩余行为:
RED: Write next test → fails
GREEN: Minimal code to pass → passes
COMMIT: Commit this working test and code
规则:
- 一次只写一个测试
- 只编写足以通过当前测试的代码
- 不要预判未来测试的行为
- 让测试专注于可观察的行为
- 提交历史应清楚展现行为的逐步增加
4. 重构
所有测试通过后,寻找重构候选项:
- 提取重复代码
- 加深模块(将复杂性移至简单接口之后)
- 考虑新代码揭示了现有代码的哪些问题
- 每完成一个重构步骤后运行测试
**切勿在 RED 阶段重构。**先达到 GREEN。
每个周期的检查清单
[ ] Test describes behavior, not implementation
[ ] Test uses public interface only
[ ] Test would survive internal refactor
[ ] Code is minimal for this test
[ ] No speculative features added
[ ] Commit has been made with working test and code