TL;DR

TDD 并未死亡,而是在 AI 时代进化为新的形态:

  1. TDD 的困境 — 红绿重构循环在 AI 生成代码时代显得低效
  2. AI-First 测试 — 从”先写测试”到”验证 AI 输出”
  3. 意图驱动验证 — 人类定义场景和边界,AI 生成测试矩阵
  4. 活的文档 — 测试即需求,需求即测试,AI 维持同步

关键洞察:测试的目的不是证明代码正确,而是建立信任。


TDD 的辉煌与疲惫

让我们先向 TDD 致敬。

2000 年代初,Kent Beck 提出测试驱动开发(Test-Driven Development),这个简单的理念彻底改变了软件行业:

  1. :写一个失败的测试
  2. 绿:写最少代码让测试通过
  3. 重构:优化代码,保持测试通过

这个循环看似简单,却解决了软件开发的几个根本问题:

  • 设计压力:测试强迫你思考接口设计
  • 回归保护:修改代码时不会破坏已有功能
  • 信心建立:重构时心里有底
  • 文档效果:测试就是最好的使用文档

TDD 的黄金时代

在 2010 年代,TDD 成为”严肃”软件开发的标志:

  • 敏捷运动:TDD 是敏捷开发的核心实践
  • XP 极限编程:测试优先是基本原则
  • 开源项目:高质量项目必须有高测试覆盖率
  • 面试标准:”你会写单元测试吗?”成为必问题

但阴影也在蔓延

然而,随着时间的推移,一些问题开始浮现:

场景一:测试维护地狱

小李的项目有 80% 的测试覆盖率,这本该是好事。但当产品经理要求修改一个按钮文案时,他花了 2 小时修改了 47 个测试文件。

“我只是把 ‘提交’ 改成 ‘保存’,为什么 47 个测试要失败?”

场景二:脆弱测试

小王的团队坚持 TDD,但他们的测试非常脆弱:

  • 修改实现细节 → 测试失败
  • 重命名内部函数 → 测试失败
  • 调整日志格式 → 测试失败

测试成了变更的阻力,而非安全网。

场景三:AI 生成代码的冲击

当 Copilot/Cursor 可以一次性生成 100 行正确代码时,经典的 TDD 循环显得笨拙:

  1. AI 生成代码
  2. 人类:”等等,我先写个失败测试”
  3. 写测试
  4. 运行测试(失败)
  5. AI:”为什么不直接让我生成正确的代码?”

这就像有了自动铅笔,却还在用削笔刀。


经典 TDD 在 AI 时代的挑战

挑战 1:测试编写速度 vs 代码生成速度

经典 TDD 假设:

  • 写测试很快
  • 写实现很慢
  • 所以先写测试能节省时间

AI 时代的现实:

  • 写测试:人工,需要思考场景和边界,较慢
  • 写实现:AI 生成,几秒钟完成,较快

速度对比逆转,导致 TDD 的时间投资回报率下降。

挑战 2:测试意图 vs 实现细节

经典 TDD 强调:

  • 测试应该关注行为,而非实现
  • 重构时测试应该继续通过

但现实是:

  • 很多测试实际上耦合了实现细节
  • AI 生成的代码可能与人类写的结构不同
  • 测试变得脆弱

挑战 3:测试覆盖率幻觉

经典观念:高覆盖率 = 高质量

AI 时代的问题:

  • AI 可以轻松生成覆盖所有分支的测试
  • 但这些测试可能没测到真正重要的场景
  • 覆盖率 100% 但 bug 依然存在

质量 != 覆盖率,这个道理在 AI 时代更加凸显。

挑战 4:测试即文档的失效

TDD 的承诺:测试就是最好的文档

现实:

  • 测试代码往往难以阅读
  • 测试关注边界情况,而非典型用法
  • 新手从测试中学到的有限

💡 Key Insight

AI 时代的核心变化是速度逆转:测试编写不再是瓶颈,意图定义成为新的价值所在。TDD 解决了”代码写得慢”的问题,但 AI-First 解决的是”需求说不清”的问题。


挑战 4:测试即文档的失效

AI-First 测试范式

核心转变

“人类写测试验证代码”“人类定义意图,AI 生成验证”

维度 经典 TDD AI-First 测试
起点 写失败测试 定义意图和场景
测试生成 人工编写 AI 生成测试矩阵
验证重点 代码行为 意图实现
维护方式 人工更新 AI 辅助同步
文档形式 测试代码 自然语言 + 测试

AI-First 测试三层模型

新模式:意图 → 场景 → 验证

新模式:意图 → 场景 → 验证


实战:从红绿重构到意图验证

场景:用户注册功能

下面通过用户注册功能,展示两种方式的典型工作流程差异。

经典 TDD 方式

以用户注册功能为例,经典 TDD 的工作流是:开发者先写一个失败的测试 test_register_valid_user_should_create_account,断言新用户可以被创建且返回正确的 ID;运行测试看到失败(红);然后编写最少量代码实现注册逻辑;再次运行测试看到通过(绿);最后进行重构,优化代码结构但保持测试始终通过。这个循环——红、绿、重构——保证了注册功能从一开始就被测试覆盖,但代价是开发者需要为每个边界条件单独编写测试:邮箱格式、手机号格式、密码强度、重复注册……一个注册功能可能有 30+ 个测试用例。

AI-First 方式

AI-First 流程则完全颠倒了这个顺序。开发者用自然语言描述注册场景的意图:「当用户提供有效邮箱和符合强度要求的密码时,系统创建用户账号并返回 ID;邮箱格式无效时返回错误;密码强度不足时返回具体提示;已注册邮箱拒绝重复注册。」这段意图描述喂给 AI,AI 自动生成完整的测试矩阵:所有合法组合、所有边界条件、所有错误路径。开发者从”写测试”变成”审意图”,AI 负责把意图转成精确的验证代码。测试覆盖率不再是人工挣扎的目标,而是 AI 生成的副产品。

关键差异

两种方式的根本分歧不在于工具,而在于思维模式:


测试即需求:活的文档

经典问题:测试与需求不同步

传统开发中:

  1. 产品经理写需求文档
  2. 开发写代码
  3. 测试写测试用例

三个文档,三个版本,很快就不同步。

AI-First 解决方案:单一真相源

当意图变更时,AI 自动更新所有下游产物。

活的文档系统

AI-First 测试的真正颠覆之处,不在于测试生成的速度,而在于它重新定义了”文档”这件事。在传统开发中,需求文档、测试用例、技术文档是三个独立维护的实体——产品经理更新了需求,开发可能忘记同步更新测试,文档就这样悄悄过时了。

AI-First 的答案是单一真相源:意图(Intent)作为唯一的权威文档,人工智能负责把它同步到所有下游产物。产品经理写好一条意图:「用户连续 5 次输入错误密码后,账号锁定 30 分钟」——AI 自动生成测试用例,自动更新场景层描述,自动维护验证矩阵。没有任何一个环节需要人工复制粘贴,没有任何同步延迟。当这条意图变更时,AI 自动重新生成所有受影响的部分。

这意味着测试不再是被动编写的文件,而是活的、会随意图自动更新的文档。需求变了,测试矩阵跟着变;边界条件调整了,验证层自动刷新。测试即需求,需求即测试——两者本来就是同一件事的两个视角。


反直觉洞察

洞察 1:AI 生成测试不是偷懒,是杠杆

担忧:让 AI 生成测试,工程师会变懒。

现实:

  • AI 生成的是”验证代码”
  • 人类需要思考的是”验证什么”
  • 后者才是高价值工作

就像计算器没有让数学家变懒,而是让他们思考更难的问题。

洞察 2:测试代码应该被生成,而非手写

反直觉:测试代码是高度模式化的,正好适合 AI 生成。

人类应该专注于:

  • 定义意图
  • 识别边界条件
  • 设计场景

AI 负责:

  • 编写具体的断言
  • 设置 mock
  • 处理重复结构

洞察 3:覆盖率应该由 AI 保证,人类保证意图

传统:人类努力达到高覆盖率。

AI-First:

  • AI 确保技术层面的覆盖率
  • 人类确保业务层面的覆盖度
  • 两者结合才是真正的质量保证

迁移路径:从 TDD 到 AI-First

阶段 1:意图显式化 (1-2 周)

目标:开始用自然语言描述测试意图

实践要点:在写任何测试代码之前,先用自然语言描述你期望的行为。

这个阶段的关键不是工具,而是习惯的转变。团队成员每天开始写测试前,先在 Markdown 或 YAML 里写一段自然语言描述:「这个函数接收一个邮箱字符串,格式正确时返回用户对象,邮箱无效时抛出 ValidationError。」写完这段意图描述后,再去写代码或测试。这个”先意图后代码”的习惯,是整个迁移的基础。

阶段 2:AI 辅助生成 (2-4 周)

目标:用 AI 生成测试模板和边界条件

工具

  • GitHub Copilot 生成测试代码
  • ChatGPT/Claude 扩展测试场景

这个阶段的标志是 AI 开始介入测试生成。团队成员把第一阶段写好的意图描述喂给 AI,让 AI 生成对应的测试代码初稿。Copilot 可以在 IDE 里实时补全测试代码;Claude 或 ChatGPT 可以根据一条意图描述生成 10-20 个边界条件的测试用例。人的角色从”写测试”变成”审测试”:AI 生成的测试覆盖是否完整?是否有遗漏的场景?人的审查能力在这个阶段得到强化,因为审查比生成更需要判断力。

阶段 3:意图驱动开发 (1-2 个月)

目标:意图成为主要工件,测试代码自动衍生

实践:意图文档在这个阶段成为团队协作的核心工件。产品经理写意图,开发审查意图并补充技术约束,QA 验证意图覆盖了所有验收标准。当意图变更时,AI 自动重新生成测试矩阵,所有相关人员收到通知并确认。这个阶段的团队发现,他们花在”修改测试”上的时间大幅减少,因为测试永远跟着意图走,不需要人工同步。旧的测试债务在这个阶段开始被偿还:旧测试被逐步替换为意图描述,代码库慢慢变轻。

阶段 4:全自动化 (3-6 个月)

目标:意图变更自动触发测试更新

实践:当意图文档推送到 Git 时,CI pipeline 自动触发 AI 重新生成完整测试矩阵,测试结果以报告形式返回给 PR。意图变更 → AI 生成 → 测试运行 → 结果回传,这条链路完全自动化,不需要人工触发任何步骤。QA 的角色进一步转变:从”写测试”到”设计验证矩阵”,即定义什么样的意图组合需要什么样的验证深度。团队在指标上会看到:测试维护成本下降,回归缺陷减少,新功能交付周期缩短——不是因为人变快了,而是因为 AI 承担了所有模式化的工作。


结尾

让我们回到根本问题:为什么要测试?

不是为了覆盖率数字。 不是为了满足流程要求。 不是为了写报告。

测试的终极目的是建立信任——

  • 信任代码在修改后依然正确
  • 信任重构不会破坏功能
  • 信任新功能不会引入回归
  • 信任团队可以持续交付

AI-First 测试并没有改变这个目的,它只是让我们更高效地达到这个目的。

TDD 没有死,它进化了。

从”测试驱动开发”到”意图驱动验证”,我们实际上是在做同一件事:用清晰的思维指导代码

只是现在,我们有了一个强大的搭档。


深度阅读时间:约 11 分钟

系列关联阅读

下一篇预告:#49 Context 工程:AI-Native 开发的核心能力


Published on 2026-03-13