tdd:让AI严格执行“红-绿-重构”的测试驱动开发
tdd:让AI严格执行“红-绿-重构”的测试驱动开发


什么是tdd技能?

tdd是Matt Pocock开发的测试驱动开发技能,在技能排行榜上以超过39万的热度排名第十。它的核心作用只有一个:强制AI在写任何实现代码之前,先写一个会失败的测试

如果你用过AI写代码,大概率遇到过这种情况——让AI加一个新功能,它直接生成了几百行实现代码,测试文件是空的,或者测试是后补的。你问“测试呢?”,AI说“哦,我补一下”。这不是TDD,这是“测试后补”(Test-After Development)。

tdd技能要解决的就是这个问题。它不是一个“让AI帮你写测试”的工具——它的本质是改变AI写代码的顺序:先写测试,看着它失败,再写最小代码让它通过,最后在绿色状态下重构。整个过程严格按照“红-绿-重构”的纪律执行

Matt Pocock本人对这套技能的评价很直接:“tdd技能本身就值得安装” 。这个技能适用于Claude Code、Cursor、Codex、Windsurf等60多个AI智能体

主要功能

1. 强制“铁律”:没有失败测试,就没有生产代码

tdd技能最核心的规则是一条铁律(The Iron Law)没有失败测试在先,就不写任何生产代码

如果AI先写了代码再写测试,规则要求:删掉代码,重新开始。不能把已经写好的代码当作“参考”,不能在写测试的时候偷偷“适配”已有的代码,不能看一眼当作灵感——删除就是删除,从头从测试开始。

2. 严格的红-绿-重构循环

tdd技能把整个开发过程拆成三个明确的阶段

红色阶段(Red) :写一个最小的、会失败的测试。要求测试名称清晰、测试真实行为、一次只测一件事。写完之后必须运行测试,亲眼看到它失败——如果测试直接通过了,说明你在测试已经存在的功能,需要改测试

绿色阶段(Green) :写最少的代码让测试通过。不要加额外功能,不要顺手重构其他代码,不要做任何“顺便优化”的事情。写完之后必须运行测试,确认全部通过——如果有其他测试失败,立刻修

重构阶段(Refactor) :只有在全部测试都绿的情况下才做重构。消除重复、改进命名、提取辅助函数。重构过程中保持所有测试始终为绿色

3. 对“坏测试”的零容忍

tdd技能对测试质量有明确要求

  • 测试必须测试真实代码,而不是mock对象(除非万不得已)

  • 测试名称必须清晰描述要测试的行为

  • 每个测试只测一件事

  • 测试之间不能共享状态

4. 多框架支持

tdd技能是语言无关的(language-agnostic)。它支持的测试框架包括Jest、Vitest、pytest、Go test、cargo test、PHPUnit和RSpec等

如何安装tdd技能

方式一:单独安装tdd技能

在终端中执行以下命令:

bash
npx skills add mattpocock/skills --skill tdd

这条命令会从Matt Pocock的技能仓库中单独安装tdd技能

方式二:安装完整技能包

如果你想一次性安装Matt Pocock的所有技能(包括tdd、grill-me、grill-with-docs、improve-codebase-architecture等),可以执行

bash
npx skills add mattpocock/skills

方式三:使用@latest版本

bash
npx skills@latest add mattpocock/skills/tdd

这种方式会拉取最新版本

安装后配置

首次使用时,运行以下命令完成配置

text
/setup-matt-pocock-skills

选择你的问题跟踪器和文档偏好,每个仓库配置一次即可。

验证安装

安装完成后,通过以下命令确认:

bash
npx skills list

在列表中应该能看到tdd。

如何使用

安装后,在你的AI编程助手(Cursor、Claude Code、Codex等)中输入:

text
/tdd 实现一个购物车添加商品的功能

或者更简洁地:

text
/tdd add JWT authentication with refresh tokens

AI就会严格按照红-绿-重构的流程来工作

应用场景

场景一:开发新功能

这是tdd技能最常用的场景。你要加一个新功能——比如“用户注册”、“订单支付”、“文件上传”——但需求还不够具体,或者你担心AI直接写出来的代码没有测试覆盖。用 /tdd,AI会先帮你把功能拆解成一个个行为,然后逐个用红-绿-重构的方式实现

场景二:修复Bug

你发现了一个Bug,但不确定修复之后会不会引入新的问题。用 /tdd 修复Bug的标准流程是:先写一个会失败的测试来复现Bug,然后再写代码让测试通过。这样不仅能确认Bug被修好了,还能确保以后不会再复发。

场景三:重构现有代码

你想重构一段“能跑但很乱”的代码,但担心改坏了。用 /tdd,AI会先在现有代码上建立测试覆盖(确保行为被锁定),然后再进行重构。重构过程中所有测试保持绿色,随时可以回滚。

场景四:代码评审中发现“没有测试的PR”

团队里有人在PR里提交了一大段代码,但测试文件是空的,或者测试明显是后补的。你可以建议对方用 /tdd 重新实现一遍——不是为了多写几个测试文件,而是让AI在写代码之前先想清楚“这个功能到底应该怎么被验证”

使用案例

案例一:购物车功能的TDD实现

一个开发者需要实现一个电商购物车系统——用户可以添加商品、查看总价、使用折扣码。他没有直接让AI写代码,而是输入了 /tdd 实现购物车功能

AI按照红-绿-重构的流程开始了工作:

第一轮(红色) :AI写了一个测试——空购物车的总价应该为0。运行测试,失败。绿色:AI写了Cart.total()方法,返回0。测试通过。重构:代码干净,无需重构。

第二轮(红色) :AI写了一个测试——添加一件商品后总价等于商品价格。运行测试,失败。绿色:AI修改了Cart类,添加了商品列表和总价计算。测试通过。重构:提取了价格计算逻辑到独立方法。

第三轮(红色) :AI写了一个测试——添加两件商品后总价等于两者之和。运行测试,失败。绿色:AI修改了总价计算方法,遍历所有商品求和。测试通过。

经过多轮迭代,购物车功能完整实现,每一步都有对应的测试覆盖,而且每个测试都是“先失败、后通过”的——AI亲眼看着每一个测试从红变绿

案例二:Bug修复——先复现再修复

一个团队在维护一个内部系统,用户反馈说“折扣码在订单金额为0的时候报错”。以前的习惯是:开发人员直接去看代码,猜哪里出了问题,改完提交。

这次用了 /tdd。AI先写了一个测试:创建一个金额为0的订单,应用一个折扣码,期望不报错。运行测试,失败(复现了Bug)。然后AI开始看代码,发现是折扣计算逻辑里没有处理除数为0的情况。AI写了最小代码——在计算折扣前判断订单金额是否为0,如果是则直接返回0。再次运行测试,通过。

Bug修好了,而且仓库里多了一个测试,以后永远不会再犯同样的错误

案例三:从“AI乱写”到“AI按纪律写”

一位开发者在一篇文章里分享了他的经历:他让AI“实现一个用户认证模块”,AI直接生成了300多行代码——JWT生成、密码哈希、登录接口、注册接口、中间件,全部一次性写完。看起来很厉害,但测试覆盖率几乎为零,而且代码里有一些明显的边界情况没处理。

他装上tdd技能后,重新提了同样的需求,但这次用的是 /tdd 实现用户认证模块。AI没有一次性输出300行代码,而是先问:“你想先实现哪个行为?登录、注册、还是刷新Token?”他选了登录。AI写了一个测试——“用户名密码正确时返回JWT令牌”——运行失败,然后写了最小实现让测试通过,再重构。一个行为一个行为地来,每个行为都有测试保护。

最后同样是300多行代码,但这次每一行都有对应的测试,而且AI在写每一段代码之前都亲眼看着对应的测试失败过

案例四:社区的真实评价

在Vercel社区中,有用户评价说:“tdd技能本身就是值得安装的”。另一位用户在文章里写道:“tdd是整套技能的核心编码标准,强制遵循行业权威的‘红-绿-重构’流程,从根源解决代码无测试、Bug频发、代码冗余问题”

总结

tdd技能解决的是一个非常朴素但极其重要的问题:AI写代码很快,但AI写的代码不一定有测试,不一定可靠

  • 强制改变顺序:先写失败测试,再写实现代码,最后重构

  • 铁律约束:没有失败测试在先,不写任何生产代码

  • 一次只做一件事:红色阶段只写测试,绿色阶段只写最小实现,重构阶段只做重构

  • 生态验证:39万+热度,全榜第十

如果你希望AI生成的代码有测试覆盖、有质量保障、不容易出Bug,tdd技能可能是你装过的所有技能里,最能改变AI“乱写代码”习惯的那一个。装上它,让AI先撞上失败测试,再把代码逼到绿色