关于 tdd
一套面向编码 Agent 的测试驱动开发指南,以可执行测试验证行为,并通过逐步的红—绿—重构循环保持快速反馈。
主要功能
- 01逐步执行红—绿—重构循环
- 02先验证失败测试再改代码
- 03优先测试可观察行为
- 04根据反馈速度选择测试边界
- 05覆盖新功能、缺陷与重构流程
适用场景
- 01为新功能编写行为测试
- 02用回归测试复现并修复缺陷
- 03在重构前固定现有行为
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ petekp/ claude-code-setup --skill tdd安装后在 Claude Code 中输入/tdd确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
bugfixes.mddeep-modules.mdinterface-design.mdmocking.mdrefactoring.mdseams.mdtests.mdagents/openai.yaml详细介绍
测试驱动开发
将可执行证据视为事实依据。使用此工作流,避免五种常见的 Agent 失误:
- 以猜测代替验证
- 还没学到任何东西就编写大量测试
- 测试结构或内部实现,而不是行为
- 过度模拟由你控制的代码
- 让反馈循环变得过慢,导致 TDD 无法发挥作用
开始会话
编辑代码前:
- 阅读仓库本地说明,例如
AGENTS.md、CLAUDE.md以及 package 或 test 脚本。 - 检查附近的生产代码和测试,推断命名方式、切入点、测试夹具以及最快的针对性命令。
- 预先确定两个命令:
- 运行单个目标测试的最快命令
- 完成前验证已更改边界的范围更广的命令
- 选择能够验证行为的最小公共或近公共切入点。参见 seams.md。
- 只有当公共契约、预期行为或所需覆盖范围存在实质性歧义时,才询问用户。
如果仓库本地说明更严格,请遵循这些说明。
纵向推进
不要先批量编写所有测试,再统一实现。
Wrong:
RED: test1, test2, test3
GREEN: impl1, impl2, impl3
Right:
RED -> GREEN -> REFACTOR: test1 -> impl1
RED -> GREEN -> REFACTOR: test2 -> impl2
RED -> GREEN -> REFACTOR: test3 -> impl3
编写一个失败的测试。用最小且合理的改动使其通过。仅在测试通过后重构。重复此过程。
选择切入路径
新功能
- 从值得交付的最小用户可见或调用方可见行为开始。
- 在选定的切入点编写一个示踪弹测试。
- 确认测试因正确的原因失败。
- 实现最精简的代码切片,使测试通过。
- 只有在当前行为得到验证后,才添加下一项行为。
Bug 修复或回归问题
- 修改代码前,列出 2-3 个合理的假设。
- 编写能复现问题的最小失败回归测试,以便及时发现此问题。
- 如果首次复现不够明确,就通过日志、断言或更低层的切入点缩小复现范围。
- 在该失败测试的约束下修复代码。
- 仅当一个相邻测试能证明修复具有针对性而非偶然奏效时,才添加该测试。
详细的迷你循环参见 bugfixes.md。
遗留代码或重构
- 在调整内部结构前,用特征测试固定当前行为。
- 在这道安全防线上进行重构,直到设计呈现出更好的切入点。
- 切入点改善后,用更精确的行为测试替换覆盖范围过广的特征测试。
- 利用绿色状态深化模块并简化接口。
参见 seams.md、deep-modules.md 和 refactoring.md。
运行核心循环
每个周期:
RED:编写或完善一个用于验证单项行为的测试。确认它会失败。GREEN:编写最少的生产代码改动,仅使该行为通过测试。REFACTOR:在保持测试通过的同时,清理重复代码、命名和结构。- 先重新运行最小范围的相关命令,再随着信心增强扩大验证范围。
如果测试无法失败,这个循环就无效。主动让它失败、降低切入层级,或补充缺失的可观测性,然后再信任测试结果。
保持反馈迅速
按以下阶梯逐步验证:
- 迭代时运行单个目标测试。
- 经过一小组绿色循环后,运行相关文件、package 或针对性测试套件。
- 完成前进行更广泛的验证:相关集成测试套件、类型检查、lint,或针对已修改边界运行完整测试。
- 如果时间、工具或环境导致无法进行更广泛的检查,请明确指出验证缺口。
如果循环感觉太慢,切入点可能过高。降低一个层级,除非该行为确实发生在浏览器中或跨越系统边界。
选择经得起重构的断言
- 断言可观察到的结果,而不是辅助函数调用。
- 优先使用公共接口,而不是内部协作者。
- 只模拟你无法控制的系统边界。请参阅 mocking.md。
- 将测试视为行为规范,而不是实现形式的快照。
- 每个测试只关注一种行为,即使验证这种行为需要多个断言。
示例和改写请参阅 tests.md。
谨慎使用子 Agent
其他 Agent 提供帮助时:
- 在主线程中负责失败的测试、红绿循环和最终验证。
- 让工作者在现有失败测试的约束下探索实现方案或重构。
- 除非测试验证的是错误行为,否则拒绝那些只靠削弱测试才通过的修复。
避免以下反模式
- 还没看到有意义的失败测试,就为目标行为修改生产代码
- 预先写好整个测试计划
- 在一个红绿循环中解决多种行为
- 对于可以通过其他方式更快验证的逻辑,使用浏览器或端到端测试
- 仅为方便测试,就模拟自己负责的模块
- 留下调试脚手架、推测性的分支或未经验证的重构
用证据收尾
只有满足以下条件,才算完成任务:
- 修改后的行为由一个在修改前会失败的测试覆盖
- 目标测试通过
- 已运行相关的更广泛验证命令,或清楚记录未运行的原因
- 只在测试通过时进行重构
- 最终总结说明现在已验证的行为,以及仍需手动验证的部分
按需深入阅读
- tests.md:持久的行为级断言,以及从较差到较好的改写
- mocking.md:仅模拟系统边界的规则
- seams.md:接缝选择、测试级别和快速反馈
- bugfixes.md:先写回归测试再调试
- interface-design.md:可测试的接口
- deep-modules.md:通过小型 API 隐藏复杂性
- refactoring.md:仅在测试通过时进行的清理目标
评论
支持 Markdown