tdd — 强制测试驱动开发,不跳过测试
Matt Pocock 出品,严格执行 RED→GREEN→REFACTOR 循环,确保 AI 写的每一行代码都有测试覆盖,杜绝'先写代码后补测试'。
评分明细
适用场景
tdd 快速入门
强制 AI 按 RED → GREEN → REFACTOR 循环写代码,让”先写实现后补测试”变成不可能。
这是什么?解决什么问题?
测试驱动开发(TDD)是个老话题,它的核心循环非常清晰:
- RED:先写一个失败的测试(因为还没有实现);
- GREEN:写最少的实现代码让测试通过;
- REFACTOR:在测试保护下,清理实现,提升可读性/性能。
但 90% 的团队嘴上说 TDD,实际是”先写代码,上线前赶测试”——尤其是用 AI 写代码,默认行为是直接给实现,测试要你主动要求。
Matt Pocock 的 tdd Skill 把这个循环强加给 AI:
- AI 想写实现,先被强制”先写一个会失败的测试”;
- 测试必须真实运行(命令可见),而不是嘴上说”应该失败”;
- 改实现时,测试必须保持绿;
- 重构时,测试覆盖不能减少。
这样保证 AI 写的每一行生产代码都有对应的测试保护。
适合:所有”用 AI 写代码但又担心质量”的工程师,尤其是金融/医疗/企业级应用。
准备工作
- 一个支持 SKILL.md 的 agent
- 一个带测试框架的项目(Jest / Vitest / pytest / Go test / JUnit 均可)
- 测试能跑通的命令(如
npm test) - 5 分钟
3 步快速上手
第 1 步:克隆并软链
git clone https://github.com/mattpocock/skills.git
ln -sf "$(pwd)/skills/tdd" ~/.claude/skills/tdd
OpenCode 用户把目标路径改为 ~/.config/opencode/skills/,Cursor 用户改为 ~/.cursor/skills/。
第 2 步:确认 Skill 加载
cat ~/.claude/skills/tdd/SKILL.md | head -30
应当能看到 RED/GREEN/REFACTOR 三个阶段的具体动作定义(必须真实跑测试、必须看到失败、必须看到通过、refactor 时测试仍绿)。重启 agent,/skills list 看到 tdd 即 OK。
第 3 步:用 Skill 写第一个 TDD 函数
在 agent 对话里说:
[开 tdd]
用 TDD 帮我写一个 formatPrice(amount: number, currency: 'USD' | 'CNY'): string 函数。
规则:amount 保留 2 位小数,US 用 $,CN 用 ¥,负数前加 -。
观察 AI 行为:
Step 1 (RED):AI 先写 src/formatPrice.test.ts:
import { formatPrice } from './formatPrice';
test('formatPrice USD 100 → "$100.00"', () => {
expect(formatPrice(100, 'USD')).toBe('$100.00');
});
跑 npm test,必须看到失败(因为还没实现)。
Step 2 (GREEN):AI 写最少代码让测试绿:
export function formatPrice(amount: number, currency: 'USD' | 'CNY'): string {
const sign = amount < 0 ? '-' : '';
const abs = Math.abs(amount).toFixed(2);
return `${sign}${currency === 'USD' ? '$' : '¥'}${abs}`;
}
Step 3 (REFACTOR):AI 重新看代码,可能把 currency 抽成字典,跑测试保持绿。
整个过程你都能看到 AI 在做事的”证据”(终端输出、文件 diff),而不是黑盒说”写好了”。
常见踩坑
- RED 阶段 AI 不真跑测试:“写好了应该失败”不算数,要让 AI 把
npm test实际跑起来,把失败信息贴出来。Skill 默认会强制。 - GREEN 阶段过度实现:写了一堆测试没要求的功能,违反”最少实现”原则。明确说”先只通过当前测试,不要加额外逻辑”。
- REFACTOR 阶段偷偷改测试:refactor 是改实现不是改测试,如果测试变了,可能掩盖实现 bug。Skill 会显式禁止。
- 测试不写断言:AI 写出
test('it works', () => {})这种空测试,Skill 应当能识别并提示”无效测试”。 - 依赖外部服务时跑不通:测试需要数据库 / 网络时,没 mock 导致 RED 阶段也连不上。提前准备好 mock 框架(MSW、testcontainers)。
- 100% 覆盖率执念:TDD 不等于 100% 覆盖,branch coverage 100% 是过度目标,关注核心业务路径即可。
初级用法
- 每个新函数都 TDD:写工具函数、helper、纯函数,先开 tdd Skill,养习惯。
- 修 bug 走 TDD:发现 bug 后,先写一个能复现 bug 的测试(RED),看到失败,再修实现(GREEN)。
高级玩法
- CI 强制 RED/GREEN 日志:在 PR 里贴 AI 跑测试的终端输出,reviewer 一眼能看出是不是真 TDD。
- TDD + Property-based Testing:Skill 跑完后追加”再补 3 个 fast-check 属性测试”,覆盖边界。
- 配合 mutation testing:用 Stryker/Stryker4s 验证测试”真的能抓到 bug”,而不是只跑过。
小技巧
- 测试名要能”读出来就知道在测什么”,如
formatPrice should return $100.00 when amount is 100 and currency is USD,Skill 会主动用这个风格。 - 一个测试只测一个 case,不要塞 5 个 expect 进同一个 test。
- 边界值、空值、负值、极值,Skill 默认会问”还要测哪些 case”,回答它。
- 跑测试时设
--bail(Jest)/-x(pytest),第一个失败就停,节省时间。 - 写完 TDD 三个循环,顺手
git add -A && git commit -m "feat: formatPrice",留下清晰历史。
常见问题 FAQ
Q1: tdd 适合哪些编程语言?
A: tdd 通常支持主流编程语言(Python、JavaScript/TypeScript、Java、Go、C++、Rust 等)。支持程度因语言而异:Python/JavaScript/TypeScript 最佳,小众语言(如 Haskell、Elixir)可能较弱。
Q2: tdd 生成的代码可以直接用吗?
A: 简单的 CRUD、工具函数、单元测试可以直接用;复杂的业务逻辑、算法实现需要人工 review。永远不要盲目复制 AI 生成的代码——先理解再使用。
Q3: tdd 怎么收费?
A: 通常分免费版(基础功能,有限次数)、付费版(高级模型、无限次数、团队协作)。个人开发者 Pro 版约 $10-20/月,企业版 $30-50/用户/月。具体以 https://github.com/mattpocock/skills 定价为准。
Q4: tdd 会上传我的代码到云端吗?有隐私问题吗?
A: 大部分 AI 编程工具会保存你的代码用于服务提供(模型推理)和模型改进(除非关闭)。敏感代码(企业核心、商业秘密)建议:1) 使用本地部署版本;2) 关闭”使用我的代码改进模型”选项;3) 考虑企业版(有更强隐私保护)。
Q5: 怎么让 tdd 生成更高质量的代码?
A: 关键技巧:1) 写清晰的 prompt,说明输入输出和约束;2) 提供代码示例(让 AI 学习你的风格);3) 拆分任务,不要一次生成太多;4) 用 TODO 注释让 AI 补充具体实现;5) review + 单元测试保证质量。
进阶学习建议
如果想进一步用好 tdd,建议按以下路径学习:
第 1 周:熟练使用
- 完成 3 步快速上手,跑通第一个任务
- 试 2-3 个不同场景的真实任务
- 记录”哪些 prompt 有效、哪些没用”——形成自己的 prompt 笔记
第 2 周:理解机制
- 阅读 Skill 的官方文档(README、SKILL.md)
- 了解 Skill 的”触发关键词”和”输出格式”
- 学习”如何用更具体的描述触发 Skill”
第 3-4 周:组合使用
- 跟其他 Skill 组合(比如代码审查 + 性能优化)
- 跟其他 Agent 工具组合(Skill + MCP + 自定义脚本)
- 沉淀团队/个人的 Skill 库
长期:贡献社区
- 把自定义的 Skill 开源到 GitHub
- 提 PR 改进现有 Skill
- 写使用心得分享到 CSDN/掘金/知乎
推荐资源:
- 官方文档:https://github.com/mattpocock/skills
- 官方仓库 README 里的 Examples
- 社区最佳实践:Anthropic 官方博客 https://www.anthropic.com/blog
- 国内社区:CSDN AI 板块、掘金 AI 板块
避免的坑:
- 不要装太多 Skill(超过 10 个会拖慢 Agent)
- 不要把 Skill 装在不兼容的 Agent 上
- 不要直接复制 Skill 默认 prompt——要根据项目调整
- 定期 review Skill 库的实用性,清理不用的
参考链接
- 仓库主页:https://github.com/mattpocock/skills
- Matt Pocock 个人站:https://www.mattpocock.com/
- 《Test Driven Development by Example》(Kent Beck)
- Jest 文档:https://jestjs.io/
- pytest 文档:https://docs.pytest.org/
- fast-check:https://fast-check.dev/
- 相关 Skill:diagnose、caveman、security-auditor
本文基于官方文档和公开资料整理,AI辅助生成,MagicNetWorld 尚未完成独立实测。如有错误或过时信息,请通过 contact@magicnetworld.com 反馈。
基本信息
| 项目 | 详情 |
|---|---|
| 来源仓库 | mattpocock/skills |
| 作者 | Matt Pocock |
| Stars | 68,000+ |
| 协议 | MIT |
安装
npx skills@latest add mattpocock/skills
# 选 tdd
安装后 /tdd 开启 TDD 模式。
为什么需要这个 Skill?
让 AI 写代码时,如果不加约束,典型流程是:
❌ 直接写实现 → 手动测试一下 → 看起来能用 → 提交
问题:
- 没有测试 = 无法重构
- 没有测试 = 别人不敢改
- 没有测试 = 改了不知道坏了
tdd Skill 强制执行测试先行,让 AI 像有纪律的工程师一样工作。
TDD 三步循环
🔴 RED — 先写一个失败的测试
🟢 GREEN — 写最少的代码让测试通过
🔵 REFACTOR — 重构优化,保持测试绿
实际执行示例
你: /tdd 实现一个邮箱格式验证函数
AI:
🔴 RED: 先写测试用例
test('valid email', () => {
expect(validateEmail('user@example.com')).toBe(true)
})
test('invalid - no @', () => { ... })
test('invalid - no domain', () => { ... })
test('edge case - unicode', () => { ... })
运行测试 → 4 个全红 ❌(函数还不存在)
🟢 GREEN: 最小实现
function validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
运行测试 → 4 个全绿 ✅
🔵 REFACTOR: 提取常量,优化正则
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
function validateEmail(email) {
return EMAIL_REGEX.test(email)
}
运行测试 → 仍全绿 ✅ → 提交
核心价值
- 防止 AI 跳过测试 — 不用这个 Skill,AI 经常”忘了”写测试
- 确保测试质量 — AI 写 4 个测试覆盖边界,而不是敷衍 1 个
- 可重构 — 有测试兜底,放心改实现
- 回归保护 — 以后改相关代码,测试会告诉你有没有破坏
适用场景
| 场景 | 效果 |
|---|---|
| 新功能开发 | 最佳 — 从零开始 TDD |
| Bug 修复 | 先写复现测试,再修 Bug |
| 重构 | 用测试确认行为不变 |
| AI 生成的代码 | 补测试,确保可靠 |
注意事项
- TDD 一开始比直接写代码慢(写测试花时间),但总体更快(少返工)
- 不适合纯 UI 调整(“把按钮改成蓝色”)
- 需要项目已配置测试框架(Jest/Vitest/pytest)
参考资料
快速安装
git clone https://github.com/mattpocock/skills.git
ln -sf "$(pwd)/skills/tdd" ~/.claude/skills/tdd