等级 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? 跑一个月,统计两个数:它报的问题里,真问题占比多少(精确率);线上出的问题里,它当时报过多少(召回率)。精确率太低(噪音多)就调提示词收窄范围;召回率太低(漏太多)说明它没拿到足够上下文。凭感觉判断有没有用,一个月后就会不了了之。

相关