编程 TDD 在 agent 循环里:真实价值,还是表演?

2026-09-07 18:12:22

TDD 在 agent 循环里:真实价值,还是表演?

Thoughtworks 杰出工程师 Birgitta Böckeler 在 Fowler 博客发布了一项探索性实验:让编码 agent 完全在自己的循环里遵循 TDD(先写失败测试、再写实现、看测试变绿)工作流,到底有没有价值?

三种用法

TDD 与 AI 辅助编码结合有三种方式:人写测试(自然语言/BDD/直接代码),AI 写实现让测试通过;人做评审检查点(AI 写失败测试、人确认测的是想要的行为、AI 再写实现);完全在 agentic 循环里(提示 agent 先逐条写失败测试、再写实现、检查之前失败的测试变绿)。第三种当前最常见,但也最值得怀疑:对人类有用的纪律,对 agent 是否同样有益?

实验设置

任务:三个规模(小/中/大)的全新业务逻辑实现,用 Claude 生成一批带特殊逻辑的提议以增加方案间差异。所有 run 都要求至少 80% 覆盖率。用 Sonnet 4.6 生成方案;独立 agent(Sonnet)评估 TDD 遵循度;Opus 4.8 在不知道方案如何生成的情况下比较质量,并现场创建 rubric 交给评估 subagent。

结果:没有明显差异

五批方案(每批两个 TDD + 两个非 TDD)。小任务和中任务呈现模式:Opus 把两个非 TDD 方案排第 1、2 名,两个 TDD 方案排第 3、4 名。只有一次——在 TDD prompt 里加了更明确的 refactor-and-design-review 步骤后——TDD 方案排第 1,但同一批里用相同 prompt 的另一个 TDD 方案却排最后。大任务 TDD 居中,两个非 TDD 拿了最好和最差。变异分数(mutation score)也没有有意义差异。结论:基于 Opus 对结果质量的判断,TDD 与非 TDD 没有可辨别的差异,非 TDD 甚至略高。

为什么:agent 不做前置设计

让 Opus 带着"哪个用了哪个工作流"的知识看会话轨迹,它发现非 TDD 和 test-first 的 run 总是在写任何代码或测试之前先做完整设计(架构、数据类型、边界情况、契约),而不是一个需求一个测试地推进——这似乎让数据模型略好、跨切面边界情况更全、功能完整性更高。TDD 指令实际上阻碍这种前置设计:那些 run 的设计由大量局部最小决策累加而成、很少被重新审视,往往落在第一个测试偶然锁定的形状上;agent 没想到要写测试的行为根本没被实现。

Ivett Ördög 的理论:AI agent 的训练数据里绝大多数是完整函数和函数描述,真正的逐步 TDD 例子只占极小部分。LLM 对代码的内部表征是"需求到代码的直接翻译",而不是"如何到达那个表征的过程"。

逐条检验 TDD 的目标

  • 先写测试避免同义反复:实验里有些 TDD 会话照样出问题——测试对实现自身跑一遍来产生"预期"答案。先写测试只是降低概率,不能可靠防止。
  • 红绿证明测试有效:人不在循环里时,看测试变红只是证明 agent 跑了并看到失败,不是失败原因正确。TDD run 的变异分数也并无更优。
  • 驱动更好设计:实验至少没有证明 TDD run 设计更优,甚至更差。人先写测试必须承受"还不知道怎么实现就先规定行为"的摩擦;agent 没有这种体验,它可以在同一瞬间写出测试和实现计划。中间没有人的检查点时,先写测试还剩什么目的?
  • 小步前进 YAGNI:限制只写让下一个测试通过的代码,对 agent 是否还有同样的约束意义值得怀疑。

实践建议

如果你的团队在努力让 agent 用 TDD,先问清楚目标:要的是测试资产,还是 TDD 工作流本身?本实验的初步信号是——agent 循环里,前置完整设计(再写实现)可能比逐测试推进产出更好;测试有效性用变异测试来监控,而不是相信"红绿"表演。这是小样本探索,值得更大规模的对照实验。

来源:TDD inside the agent loop - theater or actual value? - martinfowler.com

复制全文 生成海报 TDD AI编程 agent 工程实践

推荐文章

程序员茄子在线接单