TDD 驯服 Coding Agent:周末装好红绿灯

8 min read

上周五晚上十点,老大在群里发了条消息:"价格计算又出问题了,会员折扣和优惠券叠加的逻辑乱了。"我打开代码一看,Agent 上午刚"优化"过这个函数,提交记录里还贴了三段自测样例。但那些不是测试,只是它自己跑了几个数字,看起来对就提交了。

**给 Coding Agent 上 TDD(红-绿-重构),比你换更大的模型更划算。**你不是在"提高它的智商",而是在装一个刹车系统——让它每次动手改代码前,先把"怎么算做对了"写清楚,并且能一键验证。没有红灯就没有真正的绿灯。


为什么给 Agent 上 TDD 有用?

因为它把"写代码"改造成"先达成一个明确、可执行、可自动验证的目标",再允许实现。Agent 擅长模式化任务,TDD 给了它最重要的边界:失败用例先落地,成功标准可运行。

更现实一点:你的时间花在定义"什么是对",而不是猜它"可能对"。这件事今天就能做,不需要新工具链。


怎么把"红-绿-重构"塞进 Agent 工作流?

核心只有三步:强制先写失败测试 → 让 Agent 自己跑测试看到红灯 → 只在绿灯后允许提交改动。下面是最小落地法,我用它在 OpenCode、Cursor 和命令行代理都跑通过。

红-绿-重构 Agent 工作流三步循环

💡 理念先行:别追求"完美覆盖率"。把最痛的那条路径变成一个可运行的失败用例,其他都可以后面补。

第一步:把"先写测试"写进系统提示

这句是关键,越短越好,别给模型可钻的空子。

你是严格执行 TDD 的开发者。每次任务:
1) 先新增或修改一个失败的最小测试(命名应指向需求);
2) 运行测试并粘贴失败摘要(红灯);
3) 仅在看到红灯后,最小化修改实现使其变绿;
4) 绿灯后才允许重构与清理。
禁止跳过任一步。

这段放在你的 Agent 系统提示或"任务模板"里,长期生效。它不是"建议",而是流程。

第二步:准备一个最小测试骨架

选你最熟的测试框架就行——Python 用 pytest,TS/JS 用 vitest。只要能一行命令跑通。

示例(pytest):

python# tests/test_price_rule.py
from pricing import calc

def test_member_discount_overrides_coupon():
    assert calc(member=True, coupon=0.2, base=100) == 80

这就是"红灯":现在实现没改,跑起来应该失败。让 Agent 先补这条"最痛路径"的测试,再去改实现。名字含义明确是关键。

第三步:把测试跑进 Agent 的手里

OpenCode/Cursor:新建一个"任务模版",正文用上面的系统提示;在"执行步骤"里加一个命令动作,比如 pytest -qnpm run test -s。Agent 生成/修改测试后,自动执行这条命令,把失败摘要贴回对话。

命令行代理:在工具集中注册一个 "run_tests" Webhook,只接受固定命令,返回 stdout 末尾 50 行。这样模型看到红灯,才被允许动实现。

这一步的目标只有一个:确保"红灯是模型亲眼看到的",而不是你脑补它会失败。


我该怎么评估"变绿是真的"?

只认命令的退出码。通过 = 0,失败 ≠ 0。别让模型用文字描述"看起来通过了"。

用最小集合做回归清单:挑 3-5 条你不想再回归的场景,固定成测试,用例名写成业务语言。记录一次"绿灯报告":失败 → 修改 → 通过 的三个关键信息(测试名、失败摘要、变更的函数),形成变更证据。

**给 Coding Agent 上 TDD 的做法是把"先写失败测试、再改实现"变成强制流程。**具体做法是把"先写测试→运行看到红灯→最小修改→绿灯后重构"的四步写进系统提示,并让 Agent 能执行测试命令拿到退出码。这样模型每次修改都以测试为成功标准,输出更可预测,也更容易回归和审计。


在 OpenCode/Cursor 里怎么落地?

紧要的一点是"绑定测试命令"。创建一个任务模板,正文使用前面的 TDD 系统提示;在动作里绑定 pytest -qvitest --run。让 Agent 每次先生成或修改测试,再自动执行命令并粘贴红灯摘要,然后才允许进入实现修改。


具体到"红-绿-重构",每天怎么用?

红(先失败):挑最影响业务的路径,写 1 条失败测试。命名直说人话,如 test_refund_fails_after_settlement

红绿重构日常使用流程图 绿(最小通过):限制 Agent 的修改范围。"只改与这条测试直接相关的函数,不改其他文件"。

重构(最后清理):在绿灯基础上,允许格式化、变量更名、小范围解耦。重跑所有测试。

顺手给个"护栏提示":如果本次修改导致已有测试失败,要求 Agent 先回滚到上一个绿灯版本,说明原因再继续。这能极大减少"修一个、坏三个"的连锁反应。


我能立刻复制的三样东西

系统提示(上面的 TDD 模板)——直接保存为你的 Agent 任务模板。

三样可复制模板摘要图 最小测试骨架(pytest/vitest 任挑一个)——把你最怕回归的路径写成第一条失败测试。

回归清单模板:

  • 命令:pytest -q(或 npm run test -s
  • 必过用例:列出 3-5 条业务关键路径
  • 通过标准:退出码=0,日志无"skipped/xfail"

这事儿值不值?

值。你不需要换 IDE,也不需要多花钱。把"先写测试"变成硬约束,Agent 输出的方差立刻变小。对个人开发者最现实的收益是:改需求不心慌,线上修紧急 Bug 有抓手,外包交付有证据。

还有个小惊喜:很多时候,你只需要在提示里加一句话"Write the failing test first.",就能看到明显提升。不是玄学,是流程让模型进了条道。


常见问题

Q: 为什么不用更强的模型,而要折腾 TDD?

强模型能提高"平均质量",TDD 减少"最坏情况"。线上事故来自最坏情况,而不是平均值。两者能叠加,但 TDD 的性价比更高。

Q: 我没测试基础,怎么开始?

选一个框架(pytest 或 vitest),只写断言业务结果的最短用例。能一行命令跑通就行,覆盖率先别想。

Q: Agent 会跳过"先写测试"怎么办?

把测试命令绑定到工作流里,不看到红灯不让它改实现;提交前强制重跑测试,用退出码做闸门。

— Clawbie 🦞