7. tdd 技能

以测试优先的方式构建功能或修复bug,通过红-绿循环驱动代码产出

快速开始

npx skills add mattpocock/skills --skill=tdd
npx skills update tdd

源代码

功能说明

tdd 以测试优先的方式构建功能或修复 bug,一次只处理一个行为,通过红-绿循环驱动代码产出。

不会一次性写完所有测试。先把测试批量写完("水平切片")会产生针对想象中行为的测试——它们只检查结构的形状,对真实的变更会变得迟钝。相反,tdd 采用垂直切片:先写一个测试,然后只写刚好能通过它的代码,再写下一个测试,每个循环都从上一步的反馈中学习。测试只针对公共接口,这样底层的实现可以变更而测试无需跟着移动。

何时使用

输入 /tdd,或者当任务匹配时智能体会自动调用它——比如以测试优先的方式构建功能或修复 bug,或者当你说"红-绿-重构"时。

当有一个具体的行为需要构建,并且你希望测试能在重构后仍然有效时使用它。如果行为还没有确定下来,请先确定规格说明——可以使用 to-spec。当工作的核心实际上是接口的设计而不是测试时,请使用 codebase-designtdd 在规划阶段会调用它来获取深度模块的词汇。

红-绿,一次一个切片

核心理念是红-绿循环:先写一个失败的测试(红),添加刚好能通过它的代码(绿),然后为下一个行为重复这个过程——每个循环都从上一步的反馈中学习。第一个循环是一颗追踪弹:一个能证明单条路径端到端工作正常的测试,然后在此基础上向外扩展。因为你刚刚才写完代码,你确切地知道哪个行为是重要的以及如何验证它——你永远不会因为过早承诺你不理解的测试结构而超出你的"车灯照射范围"。

两条规则保持测试的真实性。一个好的测试读起来像一份规格说明("用户可以用有效购物车结账"),并且通过公共 API 执行真实的代码路径,所以重命名一个内部函数永远不会破坏它。期望值来自独立的真实来源——一个已知正确的字面量、一个手工计算的示例、规格说明本身——而不是用代码计算相同结果的方式重新计算,否则就是同义反复的测试,天生就会通过,什么也告诉不了你。

重构只在测试套件全部变绿之后进行;在红的时候绝不重构。

成功的标志

  • 它先写一个测试,让它通过,然后才写下一个——而不是先写一批测试再写一批代码。
  • 测试命名的是行为而非内部实现,并且能在内部重命名后仍然存活。
  • 期望值是来自规格说明的字面量,而不是用与代码相同的方式推导出的数值。

在整个流程中的位置

tdd 是主构建链在编写代码时运行的红-绿循环:

grill-with-docs → to-spec → to-tickets → implement → code-review

implement 是链中的构建步骤,它在内部驱动 tdd 以测试优先的方式构建每个任务,然后交给 code-review 评审——所以 tdd 是那个步骤内部的引擎,而不是一个独立的步骤。你也可以直接调用它,只要有具体的行为需要构建而不需要完整的规格说明时就可以。它的另一个相邻技能是 codebase-designtdd 依赖它来找到值得在其上进行测试的深度模块接缝。当你不确定哪个技能或流程适合时,可以找 ask-matt 帮你导航。

标签:LLMSkillsAI编程