tdd — 强制测试驱动开发,不跳过测试
Matt Pocock 出品,严格执行 RED→GREEN→REFACTOR 循环,确保 AI 写的每一行代码都有测试覆盖,杜绝'先写代码后补测试'。
评分明细
适用场景
tdd 快速入门
强制 AI 按 RED → GREEN → REFACTOR 循环写代码,让”先写实现后补测试”变成不可能。
这是什么?解决什么问题?
测试驱动开发(TDD)是个老话题,它的核心循环非常清晰:
- RED:先写一个失败的测试(因为还没有实现);
- GREEN:写最少的实现代码让测试通过;
- REFACTOR:在测试保护下,清理实现,提升可读性/性能。
但 90% 的团队嘴上说 TDD,实际是”先写代码,上线前赶测试”——尤其是用 AI 写代码,默认行为是直接给实现,测试要你主动要求。
Matt Pocock 的
tddSkill 把这个循环强加给 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",留下清晰历史。
参考链接
- 仓库主页
- Matt Pocock 个人站
- 《Test Driven Development by Example》(Kent Beck)
- Jest 文档
- pytest 文档
- fast-check
- 相关 Skill:diagnose、caveman、security-auditor
基本信息
| 项目 | 详情 |
|---|---|
| 来源仓库 | 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)
参考资料
📊 评分与标签
评分说明
总分 8.0/10 · P_优选
📊 可观测社区指标(数据核验日期:2026-07-23)
- 官方仓库与维护入口:mattpocock/skills。GitHub API 核验时触发限流,未记录无法再次确认的 Stars/Forks 精确快照,避免用估算值替代事实。
📦 可安装性 2.0/2.5
- 官方来源提供可复制的 Skill、MCP 或 Markdown 目录;安装前仍需按 README 配置宿主客户端、运行时和最小权限凭据。
- 来源:官方仓库
- 与 Anthropic Skills、OpenCode Skills 对比,本项遵循开放目录思路,但插件命令、脚本依赖和更新方式并不完全统一。
🎯 实用性 2.0/2.5
- 强制 RED、GREEN、REFACTOR 并用测试证明行为;这里只确认官方材料明确描述的范围,未把未经实测的准确率、性能或生产收益计入评分。
- 来源:官方功能说明
- 与 GitHub CLI、Zapier 等专用工具对比,Skill 更适合把操作步骤交给 Agent 复用,不能替代完整运行时、监控和人工验收。
📖 文档质量 1.6/2.0
- README、技能目录或官方参考页可核对安装、能力和约束;未发现统一的端到端性能基准,因此采用保守文档分。
- 来源:官方文档
- 与 Vercel Agent Skills、Obra Superpowers 对比,目标任务说明直接,但版本迁移、失败恢复和跨平台案例仍依赖上游维护。
👥 社区活跃 1.1/1.5
- 仓库公开提交历史、Issue 与 Pull Request 入口可追踪维护;因 API 限流未写入易变精确计数,社区分不依据未经复核的热度数字。
- 来源:官方维护入口
- 与 anthropics/skills、obra/superpowers 对比,具备公开协作入口,但不能据此推导响应时效、长期承诺或企业支持等级。
🔗 兼容性 1.3/1.5
- 可在能够读取 Skills/MCP 指令并具备相应工具权限的 Agent 环境使用;API、Token、浏览器和本地工具链会形成额外约束。
- 来源:官方兼容性依据
- 与 Claude Code、Codex、Cursor 的原生扩展对比,开放文件格式便于迁移,但触发、脚本执行和资源加载行为存在客户端差异。
评分依据可追溯至公开来源,每项分数均有明确理由和数据支撑。
🏷️ 标签说明
- 免费: 公开来源可访问;外部服务费用不计入 Skill 本身。来源:官方来源
- 测试: 核心能力与“强制 RED、GREEN、REFACTOR 并用测试证明行为”直接对应。来源:官方来源
- 代码审查: 官方材料显示其面向该使用方式。来源:官方来源
局限说明:本次为官方仓库与文档核验,未执行跨客户端、跨操作系统端到端基准测试;外部 API 配额、授权和价格可能变化,应以上游最新说明为准。
📋 来源与核验记录
- ✅ 官方仓库页面已核验:https://github.com/mattpocock/skills
- ✅ 官方文档或功能页已核验:https://github.com/mattpocock/skills
- ⚠️ 未验证(访问限制):GitHub REST API 于 2026-07-23 返回限流,未采用无法复核的精确 Stars/Forks 数值
- ⚠️ 间接来源(二手数据):未用于核心功能与维度评分
- ❌ 已删除死链:无