等级 L2 · 每天 20 分钟 · 场景:写测试→一、让 AI 补边界用例,做评审→三、用 AI 做 code review
一句话:测试和 review 是 AI 提效比最高的两块——因为它们验证成本低(跑一下就知道对不对)而人工成本高(枯燥、容易漏)。但两件事都有一个共同盲区:业务正确性只能人来判断。
学习地图
| 你的问题 | 看哪一节 |
|---|---|
| 「补测试太枯燥」 | 一、让 AI 补边界用例 |
| 「生成的测试看着对但没意义」 | 二、业务语义只能人来定 |
| 「怎么用 AI 做 review」 | 三、用 AI 做 code review |
| 「它 review 不出什么」 | 四、AI 评审的盲区 |
一、让 AI 补边界用例
为什么这活特别适合交出去
人写测试的通病是只写自己想到的情况——而你想不到的情况,正是 bug 藏身的地方。AI 在这里的优势不是更聪明,是更不怕枯燥:它会老老实实把空值、边界、异常分支都列一遍。
给 OrderService.calculatePrice 补单测。
(贴方法代码)
要求:
- 用 JUnit 5 + Mockito,照 PaymentServiceTest 的写法
- 覆盖:正常路径、优惠券为 null、优惠券已过期、
金额为 0、金额为负、超出库存
- 每个用例的方法名说明它在测什么
- 断言要具体,不要只断言 not null
最后两条很重要——不说,容易得到一堆 assertNotNull(result) 这种没有信息量的测试。
更好的用法:先让它列清单
先别写代码。列出这个方法应该覆盖的测试场景,
分成:正常路径 / 边界值 / 异常分支 / 并发场景。
我勾选后你再写。
好处有两个:你能看出它漏了什么(补上),也能看出你自己漏了什么(这才是价值所在)。经常会出现「这个场景我压根没想过」——那一刻就是这个用法回本的时候。
让它跑一遍再交付
写完跑 ./mvnw test -Dtest=OrderServiceTest,
失败的自己修到通过。如果是被测代码的 bug 导致失败,不要改测试来迁就,先告诉我。
最后半句是关键。AI 有很强的「让测试通过」倾向——测试失败时它可能改断言而不是报告 bug。明确禁止这一点。
二、业务语义只能人来定
AI 能生成语法正确、覆盖率漂亮的测试,但它不知道什么是对的。
举个具体的例子:
// AI 生成的(语法没问题,但没意义)
@Test
void testCalculatePrice() {
BigDecimal result = orderService.calculatePrice(order);
assertNotNull(result); // 断言了个寂寞
assertTrue(result.compareTo(BigDecimal.ZERO) >= 0); // 恒真
}// 你要补的(业务语义)
@Test
void 满200减30的优惠券_订单199元时不可用() {
// 这条规则 AI 不可能知道——它是产品定的
Order order = orderWith(new BigDecimal("199"));
assertThatThrownBy(() -> orderService.calculatePrice(order, coupon200minus30))
.isInstanceOf(CouponNotApplicableException.class);
}分工是清楚的:
| 谁做 | 做什么 |
|---|---|
| AI | 测试骨架、mock 装配、边界值枚举、参数化用例、跑通 |
| 你 | 断言什么才算对、业务规则用例、哪些场景真的重要 |
覆盖率是个陷阱
AI 能很快把覆盖率拉到 80%+,但覆盖率高不等于测得好。一堆 assertNotNull 能覆盖所有行,却挡不住任何 bug。
别把覆盖率当 KPI 交给 AI 冲——会得到一堆维护成本高、防护价值低的测试。要衡量就看:这些测试改坏代码时会不会红。
三、用 AI 做 code review
提 PR 前自己先过一遍
review 这个 diff。重点看:
1. 空指针、边界、类型转换
2. 并发安全(这段会被多线程调用)
3. 异常处理是否吞异常
4. 有没有用到不存在的 API 或配置项
按严重程度排序,每条说明为什么是问题、怎么改。
不要评论代码风格(有 formatter)。
最后一句省掉大量噪音——不排除的话,它会花一半篇幅说命名和空行。
让它报全,你来筛
一个反直觉的点:别让它自己筛严重程度。
如果你说「只报重要问题」,新模型会认真执行,把它判断为次要的问题直接不报——而它的判断标准和你的不一样,结果是漏报。
✅ 把发现的问题全部列出来,包括你不确定的和你认为不严重的。
每条标注:置信度(高/中/低)+ 严重程度(阻塞/建议/提示)。
我来决定处理哪些。
让它报全 + 标注,筛选权在你。这比让它替你筛可靠得多。
适合接进 CI 的场景
| 场景 | 效果 |
|---|---|
| PR 自动 review 评论 | 好——能挡住低级错误,人工 review 更聚焦 |
| 提交前本地过一遍 | 好——修完再提,省一轮来回 |
| 作为合并的强制门禁 | ⚠️ 慎重——误报会阻塞正常开发,容易被绕过 |
当增强不当门禁。 AI review 的定位是「多一双眼睛」,不是「守门人」。
四、AI 评审的盲区
它看得出来的:
- 空指针、数组越界、资源未关闭
- 并发问题(共享可变状态、锁粒度)
- 异常吞掉、错误处理缺失
- 明显的性能问题(循环里查库、N+1)
- 幻觉产物(不存在的 API、拼错的配置)
它看不出来的(这些才是 review 的真正价值所在):
- 业务逻辑对不对 —— 它不知道需求,只能看代码自洽性
- 这个改动该不该做 —— 方案层面的判断
- 和系统其他部分的冲突 —— 它只看到 diff,看不到全局
- 历史包袱 —— 「这里必须这么写,因为下游依赖这个行为」
- 团队约定的例外 —— 「这个模块我们故意不用统一框架」
所以:AI review 通过 ≠ 可以合并。 它替你省掉的是找低级错误的时间,不是判断这个改动对不对的责任。
常见追问
-
AI 生成的测试要维护吗? 要,而且要和手写测试一样对待。测试也是代码,也会因为业务变更而失效。生成完就不管的测试,很快会变成一堆红灯,然后被人加
@Disabled。 -
它能理解我的 mock 框架吗? 主流的(Mockito、MockK、Jest)都没问题。冷门框架或团队自研的测试工具,给它一个现有测试文件当参考,比描述用法有效。
-
能让它跑测试自己修 bug 吗? 能,但要设边界:「测试失败时,先判断是测试写错了还是被测代码有 bug,是后者就报告不要自己改」。不设这句,它可能悄悄改被测代码来让测试变绿——这是最危险的失败模式。
-
AI review 和人工 review 冲突了听谁的? 听人的。AI 不知道业务背景和历史决策。但如果 AI 报的是事实性问题(这个 API 不存在、这里会空指针),先验证再下结论——它在这类问题上准确率不低。
-
怎么评估 AI review 值不值得接进 CI? 跑一个月,统计两个数:它报的问题里,真问题占比多少(精确率);线上出的问题里,它当时报过多少(召回率)。精确率太低(噪音多)就调提示词收窄范围;召回率太低(漏太多)说明它没拿到足够上下文。凭感觉判断有没有用,一个月后就会不了了之。