首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >AI改代码快如闪电,传统测试崩了?试试JiTTesting!

AI改代码快如闪电,传统测试崩了?试试JiTTesting!

作者头像
乔梁-北京
发布2026-09-16 21:40:08
发布2026-09-16 21:40:08
800
举报

 一、为什么:AI 写码太快,传统测试扛不住

当 AI 编程工具(Agent/Copilot)几分钟改完一堆代码,传统测试体系出现三个问题:

1. 维护成本爆炸

AI 提交的 diff 又大又频繁,人类提前写的单元测试第二天就过时。如果每条 AI 生成的用例都当永久资产维护,人力成本会被放大数倍。

2. 传统 Hardening 测试『只守未来,不抓当下』

Hardening Test(加固测试)的设计目标是:生成时通过 → 入库 → 长期防回归。它对『本次 diff 刚引入的行为变更』不敏感——旧套件全绿,不代表新代码没埋雷。

3. 全量补静态测试不划算

AI 产量越高,静态套件越容易脆断。而埋得深的逻辑变更,常规功能测试未必能揪出来。

代码变更速度远大于人类写测试速度——传统测试默认『代码是对的』,不会主动找当前 diff 里的意外行为差异。

二、解决思路:测试分两类,临时线『按需造、双版比、可收割』

JiTTestingJust-in-Time Catching Test Generation)的核心反转是:把测试从『统一当固定资产』拆成两条线。

两条线并存,互不替代

维度

Hardening Test(永久资产)

Catching Test(临时探针)

目的

防未来回归

抓本次 diff 的行为差异

生命周期

入库,长期维护

默认不入库,用完即弃

通过条件

生成时通过

设计上期望在 diff 上失败

关键概念:Weak Catch 与 Strong Catch

同一测试在「旧版本 parent」上通过 + 在「新版本 diff」上失败 = Weak Catch(弱捕获),仅证明两边行为出现了差异。再经通用预言判断:该失败确实是 bug → Strong Catch(强捕获/真阳性);只是测试本身较真或预期变更 → 假阳性。

Passing Test 可『收割』为永久资产

这是最容易误解的点。Catching 流程里,LLM 生成的测试会在 parent 和 diff 上各跑一遍。其中在 parent 和 diff 上都通过的测试,说明它不是专为『制造失败』而写的,而是正常覆盖了行为——这类测试进入 passing 池,列为 Hardening Candidate(候选加固测试),经人工评审断言稳定性、长期价值、维护成本后,值得的才固化进库。不是 parent 通过就自动入库,但也不是全部丢弃。

一句话 永久 Hardening 资产继续存在;每次 PR 额外由 LLM 锻造一套一次性 Catching 探针抓差异,抓完就退场,只把少量『顺手写得好』的 passing 测试评审后转永久。

三、用什么工具、按什么步骤解决

核心组件

Dodgy Diff 管线(铺量型) 不猜意图,把 diff 直接当『嫌疑变异体』,LLM 生成测试区分 parent/diff 行为。简单粗暴,覆盖广,但误报多。

Intent-Aware 管线(精准型) LLM 先读 diff 标题、描述、代码 → 推断业务意图 → 列出风险点(空值、边界、状态机)→ 在 parent 上注入变异(如把 >= 500 改成 > 500、注入 return null、条件取反等 6 类标签)→ 生成『parent 过、mutant 挂』的测试 → 再拿去跑真实 diff

Meta 实测数据Intent 管线生成 811 条测试,52 个 weak catch(率 6.4%),覆盖 7.9% 的被测 diffDodgy 生成 1621 条,41 个 weak catch(率 2.5%),覆盖 4.0%。Intent 的捕获率约为 Dodgy 的 2.6 倍。

RubFake 规则评估器(确定性信号层) 识别 14 类误报模式(布尔翻转、mock 错误、反射断裂等)和 26 类风险标记(扫描执行结果与代码片段),标记可疑度,不单独定论。

LLM-as-Judge 集成(语义评分层) 多模型输出风险概率分(-1 到 +1)加等级加文字理由,聚合排序,减少人工评审量。

Human-in-the-Loop(最后一道关) 只给工程师发一句是非题——『这个行为变化是你预期的吗?』预期内点 dismiss,非预期就修代码。不让人读测试代码。

执行步骤(PR 提交触发,自动跑)

第 1 步:环境隔离

CI 拉出 parentmaster 基线)和 diff(待提交版本)两套工作副本,测试跑独立子进程,避免 APM 探针或自定义 ClassLoader 污染。

第 2 步:Diff 解析

提取变更函数/类,过滤无关文件,输出结构化 diff 摘要,喂给后续两条管线。

第 3 步:双管线并行生成

  • Dodgy:直接针对 diff 行为差异写测试。
  • Intent:推意图 → 列 risks → 造 mutant → 生成『parent 过、mutant 挂』的测试。

第 4 步:双版本验收

所有候选测试先跑 parent,必须全过(不过的说明测试本身有错,丢弃)。再把同一批测试跑 diff。仅『parent 过 + diff 挂』的留为 weak catch;parent 和 diff 都过的进入 passing 池(hardening candidate 候选)。

第 5 步:降噪排序

RubFake 打确定性规则信号 → LLM 集成打语义分 → 合起来排优先级,只把高分 weak catch 推给人审。

第 6 步:人审触达

工程师收到类似『布尔值从 true 变 false 是否预期』的提问,几秒到几分钟可完成 dismissCatching 测试本身默认不入库。

第 7 步:选择性收割

Passing 池里断言稳定、覆盖有价值、维护成本可控的,人工评审后转为 Hardening Test 正式入库。当前工程实现默认只留归档目录,不自动 push

落地节奏建议

从 0 到 1 分四阶段推进:先选一个项目跑 Dodgy 管线看 weak-catch 率和单次成本;再铺自己项目的 RubFake 规则库校准误杀率;接着接单模型语义评分,确认互补后升级多模型集成;最后上 Intent 三侧矩阵(parent/mutant/diff),并把 passing test 的收割流程跑通。别一上来就追求全自动入库。

本质JiTTesting 给传统测试体系补了一条按 diff 定制的动态防线。AI 写码越快,这条防线越值钱——但它不取代永久测试资产,而是让『临时探针』和『永久加固』各司其职。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档