Concitech AI · 深度长文
2026/10/09 09:08
AI 写代码,AI 写测试:“全绿”背后的同源错误
代码与测试共享需求误解,绿色结果形成虚假的安全感。文章解析同源错误、回归资产、测试驱动开发和变异测试的边界,提出需求契约与验收分工。

AI 交付了一份功能实现、一组测试和一张绿色成绩单。测试结果显示成功,用户验收发现错误。
矛盾的根源是答案的出处。代码表达模型理解的需求,测试表达模型理解的需求。两份文件共享同一个误解,测试通过成了错误之间的一次握手。
这是代码与测试的同源错误。它要求团队审查测试的判断依据。“AI 写测试无用”属于过度概括;“测试意味着保障”属于另一种过度概括。
核心问题是:谁定义正确答案?
一百元的订单,暴露两份文件的共同误解
一份示意需求:订单金额达到 100 元,运费为零;不足 100 元,运费为 10 元。
AI 理解的免邮门槛是“超过 100 元”,代码采用 amount > 100。金额等于 100 元的订单产生 10 元运费。模型生成的测试包含三个金额:99 元、100 元、101 元。对应的预期运费是 10 元、10 元、0 元。
边界用例存在,断言存在,测试结果全绿。错误藏在那个预期值里。
覆盖率显示金额为 100 元的分支得到执行。测试结果显示实现符合断言。需求写着另一份答案:100 元订单的运费为零。

图:运费门槛示意案例,非真实事故。代码与断言共享错误;验收规则保存正确答案。
问题与测试数量无关。十个用例和一千个用例具有各自的预期值。预期值的依据决定测试价值。模型读取实现、归纳现有行为、填入断言,形成的是一份行为副本。
行为副本具有用途:记录接口现状、捕捉行为变化、提供重构参照。行为副本与需求验收属于两种工作。概念混淆造成“保持现状”与“实现正确”的错位。
回归测试是一份资产,新增测试是一份候选
测试包含不同历史。
一组回归用例记录过往故障,包含用户反馈、业务确认和修复结论。一组兼容性用例保存公开接口的承诺。一组新增用例来自模型对本次任务的理解。
三者共享测试文件的外形,拥有不同的可信度。历史回归测试的价值包含故障记忆;接口测试的价值包含外部约束;模型新增测试需要审查其预期行为。
删除测试意味着删除团队的部分记忆。付款重复提交、退款金额精度、权限隔离、历史数据兼容,这些问题拥有真实的错误成本。已有测试资产的保护与新增测试质量的审查属于两项责任。
任务评测与生产维护关注不同问题。一次任务的成功率衡量本次修改;长期回归记录衡量多次修改之间的行为稳定性。单个模型、单组任务的成绩缺少覆盖所有项目的资格。任务分布、样本规模与统计显著性决定推论范围。“所有测试毫无价值”的结论需要覆盖不同任务和长期维护的证据。
项目需要识别的是测试的身份:业务承诺、故障记录,还是实现快照。测试文件的名字缺少这项判断的依据。
TDD 的价值来自规则,验收需要判断依据
测试驱动开发强调一个循环:失败测试、功能实现、重构。失败测试提出预期行为,开发者寻找满足该行为的实现。
AI 生成失败测试与实现,两份文件拥有先后顺序。顺序改变流程,正确性取决于测试内容。错误的运费规则拥有一份失败测试,错误实现满足它,绿色结果宣告完成。
TDD 的重要价值包含需求澄清。一个边界问题迫使团队作出决定:门槛包含等号,还是排除等号?产品负责人确认这项规则,测试记录这项规则,实现接受这项规则的约束。
人的输入包含判断,模型的输出包含执行。AI 承担用例展开、数据构造和测试代码生成,验收规则提供方向。团队给出输入、预期输出与业务理由,模型拥有了实现之外的检查依据。
另一位 Agent 负责测试,有助于形成不同视角。两位 Agent 共享含糊需求和相同假设,错误相关性构成风险。角色分离改变组织方式,经过确认的行为规则提供独立约束。人员数量与答案可信度属于不同维度。
覆盖率、变异测试、验收规则:三项职责
覆盖率回答执行范围问题:测试触达了哪些语句与分支?
变异测试回答断言敏感性问题:代码的小改动触发了测试失败吗?
验收规则回答业务正确性问题:用户期望哪种行为?
变异测试制造代码扰动,例如比较符替换、常量变化、返回值变化。扰动引起测试失败,断言具有变化敏感性。遗漏的扰动暴露了值得检查的薄弱点。

图:三种检查的职责。执行范围、变化敏感性与预期行为属于不同问题。
运费案例说明它的边界。错误实现使用 > 100,错误测试认定 100 元订单的运费为 10 元。某个变异替换比较符:> 变为 >=,测试失败。变异机制记录这次失败,认定测试识别成功,业务需求认可这个变异版本的边界行为。
这说明敏感性与正确性存在区别。变异测试具有检查价值,业务规则具有裁决价值。两者的组合优于职责混淆。
同样的问题存在于端到端测试。一段浏览器流程完成登录、下单、付款,断言检查页面出现“成功”。这个结果说明流程触达成功页面;订单金额、付款次数、退款权限需要各自的验收条件。
端到端测试接触真实系统路径,获得发现组件交互问题的机会。用户结果的判断质量来自检查内容。流程长度和截图数量缺少定义正确答案的能力。
测试失败:代码与断言的修改边界
代码与测试产生冲突,Agent 拥有两条修复路线:修改实现,或者修改断言。两条路线具有产生绿色结果的能力。
行为依据缺失,绿色结果成为修复目标。原来的问题是业务行为错误,新的目标变成消除红灯。测试文件失去约束力,修改代码的人兼任修改判卷标准的人。
团队需要一条明确的边界:验收规则的变更需要业务确认;代码与候选测试的修复接受验收规则的约束。
运费规则包含等号,代码与错误测试需要修改。业务规则发生变化,规则确认与测试更新需要对应记录。失败本身提供冲突信号,裁决需要解释预期行为。
实现细节测试拥有另一种边界。函数调用次数、内部对象结构、私有方法名称,包含维护成本。某次重构改变了内部组织,外部行为保持契约,测试的约束对象进入审查范围。业务行为与实现细节的区分决定修改方向。
一套具有判断依据的交付流程
-
确认行为契约。任务负责人确认预期行为。契约写明输入、预期输出、边界和禁止结果。运费例子的核心条目是
amount = 100 → shipping = 0。 -
生成实现与候选测试。AI 承担代码生成,每个关键断言关联一项契约、一个历史故障或一条接口承诺。依据缺失的用例进入待审队列。
-
审查预期值。审查对象包含模型遗漏的边界、异常数据、权限和失败路径。代码输出与测试预期形成一组比较,需求契约提供另一份比较对象。
-
执行分层检查。单元测试定位逻辑问题,集成测试检查组件协作,端到端测试观察用户路径;静态分析和变异测试补充不同的故障信号。失败修复保留规则依据与变更记录。
这套流程属于工程建议,效果需要项目自身的故障数据验证。新增测试数量、覆盖率、执行耗时构成流程指标,用户故障与逃逸缺陷构成结果指标。两类成绩对应不同问题。
AI 降低了测试代码的生产成本。预期行为的确认需要投入。工程师的工作包含维护答案的依据、识别冲突和承担验收责任。
代码与测试达成一致,是一件事。软件与用户需求达成一致,是另一件事。可靠交付需要第二种一致。
