AI 编码时代的 TDD

在 AI coding 场景下,把 TDD 视为可执行规格、任务边界和自动验收器的工作方式。

#type / synthesis #status / growing #tech / dev / test #tech / ai

[!info] related notes

AI 编码时代的 TDD

范围

这篇笔记关心的不是传统 TDD 定义本身,而是一个新问题:

为什么在 AI coding 时代,TDD 反而更重要,而不是更过时。

为什么要把这些内容放在一起理解

AI 最容易出现三类问题:

  • 写出“像对的代码”,但不一定真的对
  • 一次跳太多步,把多个需求混在一起实现
  • 在大上下文里不断追加生成,局部设计越来越脏

TDD 正好对冲这三类风险,因为它会把任务收束到:

  • 一个明确行为
  • 一个可执行测试
  • 一个最小实现
  • 一个可验证的重构步骤

一个核心判断

在 AI 时代,TDD 不只是开发习惯,更像 agent 的:

  • 可执行规格
  • 局部任务边界
  • 自动验收器
  • 重构安全网

这也是为什么“先让 AI 写一大坨代码,再顺手补测试”通常不稳。那是 test-after,不是 TDD。

AI-TDD 更稳的工作流

1. 先由人写测试清单

这一层本质上是在切需求、定边界、排优先级,最好不要完全外包给模型。

2. 让 AI 只写一个 failing test

要求它:

  • 只覆盖当前一个行为
  • 不要实现代码
  • 不要一次写多个场景

3. 人确认测试是否真的代表需求

因为 AI 很容易写出“形式正确但业务不准”的测试。

4. 让 AI 只写最小实现

明确限制:

  • 只为当前测试变绿
  • 不提前实现未覆盖逻辑
  • 不改测试去迎合错误实现

5. 先跑最小测试,再扩大验证范围

这样反馈快、定位准,也能避免每一轮都把成本拉到全量测试。

6. 再让 AI 做 Refactor

AI 连续生成时最容易把代码局部做脏,因此重构最好被显式当成单独一步,而不是默认省略。

7. 最后用独立 reviewer 或 verifier 检查

最好不要让“写的人”和“验的人”完全是同一个 prompt 视角。

Prompt 怎么写更稳

先写 failing test

先不要实现功能。
基于下面需求,只写 1 个新的 pytest 单测。
要求:
1. 只覆盖“VIP 打 9 折”这一个行为
2. 测试名要能直接表达业务意图
3. 不要生成实现代码
4. 不要一次写多个场景
5. 解释这个测试为什么应该先写

再写最小实现

现在只修改实现文件,让刚才新增的测试通过。
要求:
1. 只做最小改动
2. 不要提前实现未被测试覆盖的逻辑
3. 不要改测试
4. 返回前说明还有哪些需求尚未覆盖

最后做重构

在保持现有测试全部通过的前提下重构实现。
目标:
1. 消除重复
2. 改善命名
3. 不改变外部行为
4. 不新增无测试覆盖的分支

规则文件里最值得固化什么

如果项目里已经使用 AGENTS.md、Cursor Rules 或类似规则文件,最值得固化的是:

  • 功能改动先新增或更新测试
  • 修 bug 先写复现测试
  • 禁止通过删断言来“修”测试
  • 先跑受影响的最小测试集,再跑更大范围
  • 重构不得改变外部行为

这样做的意义,是把 TDD 从“个人习惯”升级成“仓库级执行约束”。

最短记忆方式

传统时代,TDD 帮人写出更稳的代码;AI 时代,TDD 还负责让模型别乱写。

参考资料

创建于 2026/4/23 更新于 2026/5/27