第6讲|如何让 AI 帮你补测试而不是制造脆弱测试

专栏:AI 编程提效实战 30 讲

标签:AI编程 / 单元测试 / 测试补全 / 工程效率

先说结论

AI 编程当然可以帮你补测试,但前提是你不能把它当成"测试代码生成器"。

很多人让 AI 补测试,最后得到的是一堆跑得过、但没有保护价值的用例:mock 写得很满,断言写得很松,代码一重构就碎,真正的业务风险反而没覆盖。

更稳的方式是:先让 AI 识别风险路径,再让它设计测试清单,最后只生成小范围、可验收的测试代码。

这篇给你一套可以直接复制的工作流,让 AI 补出来的测试更像工程保护网,而不是为了覆盖率凑出来的脆弱脚本。

为什么 AI 很容易写出脆弱测试

很多人的提示词是这样的:

复制代码
帮我给这个方法补一下单元测试。

这句话的问题在于,它只告诉 AI "要写测试",没有告诉它"测试应该保护什么"。

于是 AI 会倾向于做三件看起来合理、实际很危险的事:

  1. 复制实现细节,把测试写成源码的影子

  2. mock 掉太多依赖,导致用例脱离真实行为

  3. 只断言"调用了某方法",不验证业务结果

这种测试短期内可能让覆盖率变好看,但长期会带来两个问题:

  • 代码内部结构一变,测试大量失败

  • 真实线上风险发生时,测试没有任何提醒

所以补测试的关键,不是让 AI 多写几段代码,而是让它先回答一个问题:

这段代码最值得被测试保护的行为是什么?

我现在固定用的 5 步工作流

第 1 步:先让 AI 读代码,列出行为而不是测试

不要上来就说"写测试"。

第一步只让 AI 做行为识别:

复制代码
你现在是我的测试设计助手。
请阅读下面这段代码,先不要写测试代码。

请输出:
1. 这个方法/类对外承诺的核心行为
2. 输入参数的关键分支
3. 外部依赖和副作用
4. 最容易出错的边界条件
5. 代码里无法确认、需要我补充的业务规则

要求:
- 不要复述实现细节
- 不要直接生成测试代码
- 不确定的地方明确标注"不确定"

这一步的目标,是把 AI 从"代码补全模式"切到"测试设计模式"。

如果它连核心行为都说不清,后面生成的测试大概率也不值得信。

第 2 步:让 AI 先给测试清单

行为识别完成后,再让它设计用例清单。

注意,清单要按风险排序,而不是按代码行顺序排序。

复制代码
基于上一步识别出的行为和风险,请给出测试用例清单。

请按优先级输出:
1. 必测用例:不测就可能引入线上问题
2. 边界用例:空值、极值、非法输入、状态不满足
3. 回归用例:历史 Bug 或容易反复出错的场景
4. 可以暂缓的用例:收益不高或成本较高

每个用例请包含:
- 测试目标
- 输入条件
- 期望结果
- 为什么值得测

这一步很重要,因为你可以在生成代码前先删掉低价值用例。

不要让 AI 一次性把 20 个测试都写出来。先审清单,后写代码。

第 3 步:明确测试边界,不要让 mock 淹没测试

AI 写测试最常见的问题,就是 mock 写得过度。

判断一个 mock 是否合理,可以看这 3 条:

  • 外部服务、数据库、消息队列,可以 mock

  • 当前类的内部私有逻辑,不要 mock

  • 业务结果能直接断言时,不要只断言调用次数

你可以这样约束:

复制代码
现在只为"必测用例"生成测试代码。

测试边界要求:
1. 只 mock 外部依赖,不 mock 当前被测对象的内部逻辑
2. 优先断言返回值、状态变化、异常类型和关键字段
3. 不要为了通过测试而修改生产代码
4. 如果必须调整代码可测性,请先说明原因,不要直接改
5. 每个测试方法只验证一个主要行为

这段约束可以显著减少"看起来很完整、其实一碰就碎"的测试。

第 4 步:让 AI 解释断言为什么有效

生成测试代码后,不要只看能不能跑。

我会继续追问:

复制代码
请逐个解释这些测试中的断言。

对每个测试说明:
1. 它保护的业务行为是什么
2. 如果生产代码出现什么问题,这个测试会失败
3. 它是否依赖了过多实现细节
4. 有没有更稳定的断言方式

这个步骤能快速暴露两类低质量测试:

  • 断言太弱:只判断不为空、只判断方法被调用

  • 断言太脆:绑定内部步骤、私有方法、临时变量

一条好测试应该能说清楚:它在保护哪条业务约定。

如果解释不出来,就删掉或重写。

第 5 步:最后再让 AI 做可维护性检查

测试补完后,最后加一次维护性检查:

复制代码
请从可维护性角度 Review 这批测试。

重点检查:
1. 是否有重复测试同一个行为
2. 是否过度 mock
3. 是否断言实现细节而不是业务结果
4. 测试命名是否能表达场景和期望
5. 哪些测试未来最容易因为重构而误失败

请给出需要删除、合并或重写的建议。

这一步看似多余,但很省后期维护成本。

因为测试不是写完就结束,它会跟着项目跑很久。

一个完整可复制的总提示词

如果你想直接保存成模板,可以用下面这一版:

复制代码
你现在是我的测试设计助手,而不是单纯的测试代码生成器。

目标:为下面这段代码补充有保护价值、可维护的测试。

请严格按以下流程工作:
1. 先识别代码对外承诺的核心行为
2. 再列出风险路径、边界条件和外部依赖
3. 再设计测试用例清单,按必测、边界、回归、可暂缓分类
4. 等我确认清单后,只为确认过的用例生成测试代码
5. 生成代码后,解释每个断言保护的业务行为
6. 最后检查是否过度 mock、断言过弱或绑定实现细节

生成测试代码时必须遵守:
- 只 mock 外部依赖,不 mock 被测对象内部逻辑
- 优先断言业务结果、状态变化、异常和关键字段
- 每个测试只验证一个主要行为
- 测试命名要表达"场景 + 期望"
- 不确定的业务规则先追问,不要自行编造

待测试代码如下:

我的实战建议

最后给 5 条更实用的判断标准:

  1. 先让 AI 设计测试,不要先让它写测试。 测试清单比测试代码更值得你先审。

  2. 用例数量不是质量。 一个覆盖关键风险的测试,比十个只断言调用次数的测试更有价值。

  3. 断言业务结果,少断言内部过程。 这样重构时测试不容易误伤。

  4. mock 要克制。 mock 太多,测试保护的是你的 mock 剧本,不是生产行为。

  5. 让 AI 解释断言。 解释不清保护价值的测试,通常也不值得保留。

写在最后

AI 补测试真正有价值的地方,不是让你少写几行测试代码,而是帮你更快找出"哪些行为值得被测试保护"。

下一讲会继续讲一个更贴近线上问题的场景:用 AI 快速定位线上 Bug 的思路模板


如果你也在用 AI 提升开发效率,欢迎关注专栏《AI 编程提效实战 30 讲》。