关于 tdd
tdd 是指导编码 Agent 实施测试驱动开发的技能,强调通过公共接口验证可观察行为,并以单个测试与实现交替推进。
主要功能
- 01通过公共接口验证行为
- 02采用单测与实现交替的循环
- 03测试聚焦用户可见行为
- 04编写前审查测试价值
- 05测试通过后再重构
适用场景
- 01为新功能逐步添加行为测试
- 02为缺陷修复验证回归
- 03审查或精简现有测试
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bastani-inc/ atomic --skill tdd安装后在 Claude Code 中输入/tdd确认已加载。
详细介绍
测试驱动开发
理念
核心原则:测试应通过公共接口验证行为,而不是实现细节。代码可以彻底改变,测试不应该改变。
好的测试是集成式的:它们通过公共 API 执行真实的代码路径。它们描述系统_做什么_,而不是_如何做到_。好的测试读起来就像一份规范——“用户可以使用有效购物车结账”准确说明了系统具备什么能力。这些测试经得起重构,因为它们不关心内部结构。
糟糕的测试与实现耦合。它们会模拟内部协作者、测试私有方法,或通过外部方式验证(例如直接查询数据库,而不是使用接口)。警示信号:重构时测试失败了,但行为并没有改变。如果重命名一个内部函数就导致测试失败,那么这些测试测的是实现,而不是行为。
示例见 tests.md,模拟指南见 mocking.md,每个新测试都必须通过的价值关卡以及审计现有测试的工作流见 test-audit.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. 规划
探索代码库时,请使用项目的领域术语表,确保测试名称和接口用词与项目语言一致,并遵循你正在修改的领域中的 ADR。
编写任何代码之前:
询问:“公共接口应该是什么样?哪些行为最需要测试?”
你不可能测试所有内容。 与用户确切确认哪些行为最重要。将测试精力集中在关键路径和复杂逻辑上,而不是每一种可能的边缘情况。
2. 追踪弹
编写一个测试,确认系统的一项功能:
RED: Write test for first behavior → test fails
GREEN: Write minimal code to pass → test passes
这是你的追踪弹——用于证明整个路径端到端可用。
编写每个测试前,都要让它通过编写关卡:说明它保护的行为、会破坏该行为的回归问题、现有覆盖为何无法捕获该问题,以及它是否需要一个其他地方都不会使用的生产代码接缝。修复 Bug 时,第一个 RED 测试必须在未修复的代码上失败,且失败原因必须与该 Bug 的描述一致。
3. 增量循环
对于每个剩余行为:
RED: Write next test → fails
GREEN: Minimal code to pass → passes
规则:
- 一次只写一个测试
- 只编写足以通过当前测试的代码
- 不要提前考虑未来的测试
- 让测试专注于可观察的行为
4. 重构
所有测试通过后,查找重构候选项:
- 提取重复代码
- 深化模块(将复杂性封装在简洁的接口之后)
- 在适当之处应用 SOLID 原则
- 思考新代码揭示了现有代码的哪些问题
- 每完成一个重构步骤后运行测试
测试处于 RED 状态时绝不要重构。 先达到 GREEN 状态。
审查现有测试
如果要求你审查或精简测试,而不是编写测试,请遵循审计工作流:先阅读测试、对应的生产代码及其历史记录;以只读方式调查并记录每个候选项的证据;一次编辑一个连贯的批次;保留任何达到保留标准的测试。
每个周期的检查清单
[ ] Test passes the authoring gate (behavior, regression, not already covered, no test-only seam)
[ ] Test describes behavior, not implementation
[ ] Test uses public interface only
[ ] Test would survive internal refactor
[ ] Bug fixes only: the regression test failed on the pre-fix code for the intended reason
[ ] Code is minimal for this test
[ ] No speculative features added