SKILL.md
AI 翻译,以原文为准。
测试驱动开发#
TDD 是红 → 绿循环。这项技能是让该循环产出值得保留的测试的参考:什么是好的测试、测试放在哪里、反模式,以及循环的规则。每一节都适用于每一个循环:在循环之前和循环之中查阅它们,而不是之后。
探索代码库时,阅读 GLOSSARY.md(如果存在),使测试名称和接口词汇与项目的领域语言保持一致,并遵守你正在触及领域的 ADR。
什么是好的测试#
测试通过公共接口验证行为,而不是实现细节。代码可以完全改变;测试不应该。好的测试读起来像规格说明:"user can checkout with valid cart" 准确告诉你存在什么能力,而且它能经受重构,因为它不关心内部结构。
示例见 tests.md,mock 指南见 mocking.md。
接缝:测试放在哪里#
接缝是你进行测试的公共边界:你在此观察行为而无需深入内部的接口。测试位于接缝处,绝不针对内部。
只在预先约定的接缝处测试。 在编写任何测试之前,写下被测接缝并与用户确认。不在未确认的接缝处编写测试。你无法测试一切,因此事先约定接缝,是让测试工作落在关键路径和复杂逻辑上、而不是每个边缘情况上的方式。
问:"公共接口是什么,我们应该测试哪些接缝?"为每个提议的接缝给出一行说明,指出它能捕获什么、遗漏什么。
当接口本身的形态存在疑问时(模块有多深、接缝属于哪里、接口应暴露什么),调用 Skill 工具并传入 "codebase-design" 以获取词汇。它是模块、接口、深度、接缝、适配器、杠杆和局部性术语的共享来源,它是供查阅的参考,而不是要运行的会话。
反模式#
- 实现耦合:mock 内部协作者、测试私有方法,或通过侧信道验证(查询数据库而不是使用接口)。识别标志:重构时测试失败,但行为没有改变。
- 同义反复:断言以与代码相同的方式重新计算期望值(
expect(add(a, b)).toBe(a + b)、以相同方式手工推导的快照、断言常量等于自身),因此它按构造通过,永远不可能与代码不一致。期望值必须来自独立的真相来源:已知正确的字面量、一个演算示例、规格。 - 水平切片:先写所有测试,再写所有实现。批量测试验证的是想象中的行为:你测试的是事物的形状而不是面向用户的行为,测试对真实变化变得不敏感,而且你在理解实现之前就承诺了测试结构。改为按垂直切片工作:一个测试 → 一个实现 → 重复,每个测试都是一颗曳光弹,响应上一个循环教给你的东西。
循环的规则#
- 红先于绿。 先写失败的测试,然后只写足够通过的代码。不要预判未来的测试或添加推测性功能。
- 一次一个切片。 每个循环一个接缝、一个测试、一个最小实现。
- 重构不属于循环。 它属于审查阶段(见
code-review技能),而不是红 → 绿实现循环。
用途与依赖
作者没写,这些是平台读文件后整理的,以文件为准。
使用示例
请求:帮我用 TDD 给购物车加一个结算功能。
预期
技能会先询问并列出建议的测试接缝(例如 checkout(cart, paymentMethod) 这个公共接口),每条注明能捕获什么、遗漏什么,与用户确认后再开始循环。随后按垂直切片推进:先写一个失败的测试(如“用户可以用有效购物车完成结算”),再写刚好通过的最小实现,重复下一片。测试只通过公共接口断言行为,期望值使用独立已知的字面量,外部支付等系统边界才使用 mock,并提醒重构属于代码评审阶段而非红绿循环内。
- 适用场景
- 用户想以测试先行的方式开发新功能
- 用户想以测试先行的方式修复缺陷
- 用户提到 red-green-refactor 或红绿循环
- 用户需要编写集成测试而非单元测试
- 用户想评审现有测试是否耦合了实现细节
- 用户需要确定在哪些公共接口(接缝)上写测试
- 用户需要关于何时 mock、如何设计可 mock 接口的指导
- 输入
- 要实现的功能或要修复的缺陷描述
- 项目的公共接口与候选测试接缝
- 用户对测试接缝的确认
- 项目使用的语言与测试框架(如 Jest)
- 项目中的 GLOSSARY.md 或 ADR 等领域约定(如有)
- 输出
- 建议的测试接缝清单及各自能捕获/遗漏的内容
- 按红绿循环逐个产出的失败测试与最小实现
- 符合行为验证原则的测试代码
- 对反模式(实现耦合、同义反复、横向切片)的检查与修正建议
- 运行环境
- 未说明
- 依赖
- 无

