在 AI 编程工具进入工程流程后,测试生成速度明显提升,但测试结果“绿色”并不自动等同于测试有效。一位开发者在使用 Claude Code 构建多租户预约 API 时发现,在 97 个针对真实 Postgres 和 Redis 的测试中,有 6 个测试虽然通过,却没有验证其名称所声称的行为。这些测试并非语法错误或断言缺失,而是看起来合理、读起来顺畅,并且能够稳定变绿。问题在于:绿色只能证明测试执行完成,不能证明它真正覆盖了目标逻辑。
六类“假绿测试”的共同点:看起来合理,但没测到关键路径
该案例来自《Claude Code for Backend Developers》第 9 章。作者使用的技术栈包括 FastAPI、SQLAlchemy、Postgres、Redis 和后台 worker。从一开始,写测试就是明确目标,且测试直接连接真实数据库和缓存,不使用 mocked database。即便如此,仍有 6 个测试以不同方式偏离了测试意图。
- 过期 token 测试:测试构造一个过期 token 并断言返回 401,结果通过。但 token 使用了硬编码密钥签名,而应用读取的是 .env 中的另一个密钥,请求实际因签名无效被拒绝,并非因为过期。即使关闭过期检查,测试仍会通过。修复方法是加入“阳性对照”:同一个 token 只把过期时间改为未来,断言应被接受。
- 长 URL 回归测试:此前模糊测试发现,长度在 2049 和 2083 字符之间的 URL 能通过验证器,却会溢出 2048 字符的数据库列。回归测试却使用 2560 字符 URL,结果被验证器自身长度限制拒绝,返回 422,数据库路径根本没有被执行。修复方式是让测试断言前置条件:2048 < len(url) < 2083。
- 限流测试:登录功能同时检查 per IP 和 per email 两个限流。把 per-IP 检查改成失败放行后,测试仍然通过,因为 per-email 检查仍会失败。修复方法是针对每个保护机制单独植入一个 bug,并让测试路径分别触发每个防护。
- 并发竞态测试:两个线程、两个请求、一个断言。即使移除保护锁,该测试仍然 10 次运行全部通过,因为线程实际上没有发生交错。修复方式是强制制造交错:用第二个数据库连接锁住相关行,再提交请求。最终,有锁时 3 次运行全部通过,无锁时 3 次运行全部失败。
- 属性测试边界:Hypothesis 生成 −24 到 +24 小时之间的随机时长,并检查 0 < duration <= 12h 规则。把 <= 改成 < 后,测试没有失败,因为随机值几乎不会正好落在 12:00:00。修复方式是用 @example(duration=MAX_BOOKING) 及其相邻值固定边界。
- 缺失测试:一次重构破坏了 GET /bookings/{id},但整套测试仍然绿色,原因是没有任何测试成功获取过单个预约。这里的问题不是测试撒谎,而是关键场景从未被覆盖。
审查 AI 测试的关键:主动让测试失败
作者发现这些问题的方法一致:故意破坏代码,再检查是否有测试变红。随后,这套做法被脚本化。脚本维护一份“现实 bug 列表”,包括缺少租户过滤、过期未校验、重叠约束失效、限流器失败放行等。脚本依次植入每个 bug,再运行预期应捕获该 bug 的测试;如果任何 bug 没有被捕获,脚本就失败。目前已有 22 个这样的检查,并接入 CI。
这不是通用变异测试工具,而是一份针对该服务的手工挑选清单:哪些 bug 绝不能上线。由于每个植入 bug 只运行预期相关的测试文件,速度可以接受:在笔记本上运行全部 22 个检查约需一分半。这样一来,删除或削弱某个保护测试的 PR 会导致构建失败,即使其余测试全部通过。
对开发者而言,这给 AI 生成测试的审查提供了更具体的动作:
- 不要只看测试是否通过,要看它是否能让对应功能在错误时失败。
- 对每个负向断言,补充一个只改变被测属性的正向对照。
- 对依赖输入窗口、边界值或并发时序的测试,要显式固定前置条件,或主动制造边界与交错。
- 当测试因其他防护机制而通过时,需要拆分路径,确认当前防护是否真的被执行。
- 关注“没有测试覆盖”的空白,尤其是看似简单的读取、查询和详情接口。
- 植入错误后要读取究竟是哪个测试变红。如果一个预设 bug 被无关测试捕获,这是警告,而不是成功。
AI 不会让测试变得更特殊,只会更快暴露工程问题
素材指出,AI 写出的测试也会以这些方式失败,只是速度更快、数量更多。这意味着,AI 编程工具带来的并不只是“自动生成测试”的便利,也会把测试有效性问题放大到工程流程中。在 AI 大量生成测试后,“测试通过但未验证行为”的情况更容易被绿色结果掩盖。
因此,AI 编程环境下的测试 review 需要从“检查代码是否能运行”转向“检查测试是否表达并验证了意图”。测试名称、断言语句和通过状态都不足以证明有效性。真正可靠的信号,是在故意引入错误后,相关测试是否变红;是在边界、并发和依赖失效等场景中,测试是否仍然能够暴露问题。
当 AI 能批量产出绿色测试时,开发者的判断重点也要从是否通过,转向这些测试是否真的能让错误显形。
原创文章,作者:点点,如若转载,请注明出处:https://www.dian8dian.com/ai-sheng-cheng-de-ce-shi-ji-shi-quan-lyu-ye-ke-neng-mei-ce