基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
  • 知识卡片碎片时间过考点
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
    • AI 热点每日 AI 资讯与动向
AI 工作台
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-08-04 03:01

AI 生成测试的覆盖率陷阱:可执行≠有效

dev.to · AI#测试#质量#AI编程
Editor brief · 编辑速览

AI 快速生成大量测试覆盖每行代码,但缺乏有意义的断言;测试通过覆盖率高,bug 仍能上线,称为"覆盖率虚高"。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

你的 CI pipeline 显示测试覆盖率为 83%。AI assistant 在不到两分钟内生成了 27 个新的测试函数,新模块中的每个函数都有一个对应测试。PR 看起来很干净,覆盖率门禁也顺利通过。

但 bug 还是上线了。

所谓「覆盖率表演」(Coverage Theater),是指 AI 生成的测试虽然提高了代码行执行率,却没有对任何有意义的行为进行断言。指标看起来没问题,测试也确实运行了,但最终你会发现,这套测试几乎什么问题都捕获不到。

AI 如何写出提高覆盖率却不测试行为的测试

AI coding assistant 的目标往往是可量化的指标:当你让它为某个函数编写测试时,它生成的测试用例会覆盖每一行代码,却不一定覆盖每一种行为。BrassCoders 并不评估测试质量;无论测试套件覆盖了什么,它都会扫描生产代码中的安全和正确性 bug——不管覆盖率有没有达到 80%,SQL 注入 bug 都可能被发布出去。

如果把一个 hash_password 函数交给 AI,它会读取函数的结构:分支、参数类型和返回值。随后,它可能生成 assert hash_password("") is not None 和 assert hash_password("secret") is not None。这两行代码都会执行,Coverage.py 也会把它们计入覆盖率。但这些断言都无法告诉你,该函数是否使用了安全的算法,或者是否应用了 salt。即使实现从 bcrypt 换成 MD5,这两个测试也不会失败。

出现这种情况,是因为 AI assistant 根据实现推断测试,而不是根据 specification 编写测试。拿到代码后,它生成的测试只是在匹配代码当前的行为。这不叫测试,只是给 bug 拍了一张快照。

覆盖率表演的四种模式

BrassCoders 不会扫描测试质量——这超出了静态分析的范围——但覆盖率表演产生的四种模式值得明确命名:循环断言(测试断言某个函数返回的结果,正是你编写测试时它所返回的结果)、mock 被测对象、测试实现细节而不是结果,以及按照每个函数生成一个测试,而不是按照每种行为生成测试。

循环断言是其中最严重的问题。AI 在测试 calculate_tax(income, rate) 时,可能会生成:expected = calculate_tax(1000, 0.2); assert calculate_tax(1000, 0.2) == expected。除非函数抛出异常,否则这个测试无论如何都会通过。每次调用都会被记为覆盖了一行代码,但它什么也没有验证。

mock 被测对象的情况通常是这样的:你有一个数据库查询函数,于是 mock 了数据库连接,然后断言这个 mock 是否使用了正确的参数被调用。这样一来,你测试的其实是 Python 的 unittest.mock 库。真正的查询逻辑——它是否构造了参数化语句、是否正确处理 null 值——完全没有得到验证。

测试实现细节,是指针对函数内部的调用关系编写断言,而不是验证它向调用方承诺的 contract。当你重构内部实现时,即使行为没有变化,测试也会失败;而真正的回归问题仍然可能被发布出去。

第四种模式——每个函数只写一个测试——之所以能够通过覆盖率门禁,是因为覆盖率工具追踪的是代码行是否执行,而不是不同的行为路径。一个函数可能包含五种错误条件、两个边界情况和一条 happy path,却只有一个测试:测试 happy path。其余条件都没有经过测试,但这个函数仍会显示为已覆盖。

为什么指标看起来没问题,bug 却还是上线了

Coverage.py 衡量的是测试套件运行期间执行了哪些代码行——它没有任何机制判断测试中的断言是否真的能够捕获 bug。BrassCoders 可以捕获覆盖率指标遗漏的生产代码 bug:例如数据库 handler 中存在 SQL 注入,即使它拥有 100% 的代码行覆盖率,只要没有断言检查是否使用了参数化查询,这个问题依然不会被测试发现。

Martin Fowler 的 TestCoverage 文章直截了当地指出:覆盖率适合作为一种负向指标。低覆盖率肯定意味着存在问题;高覆盖率只能说明某些代码运行过,却无法说明这些运行是否能够捕获 regression。

问题源于团队对覆盖率含义的错误假设。大家默认认为:如果某一行代码被覆盖,就意味着有人编写了能够验证它的断言。在人工编写的测试中,这通常成立。但对于以通过覆盖率门禁为目标的 AI 生成测试,这个假设经常不成立——AI 编写的是能够让这行代码运行起来的断言,而不是能够捕获 regression 的断言。

Mutation testing 可以让这种差距暴露出来。Mutmut 和 Cosmic Ray 会故意向生产代码中引入 bug,然后让测试套件针对修改后的代码运行。如果存在 bug 时测试仍然通过,就说明这些测试并没有验证对应的行为。Coverage.py 文档也指出,覆盖率数据最好与其他质量信号结合使用,而不是单独作为门禁。Mutation testing 正是这样一种补充信号。

BrassCoders 能捕获哪些覆盖率工具发现不了的问题

BrassCoders 的 12 个 scanner 针对生产代码运行,而不是针对测试代码——无论测试断言了什么,它们都会捕获实现中的安全和正确性 bug。无论测试覆盖率有没有达到 80%,数据库查询中的 SQL 注入 bug 都可能被发布;而 BrassCoders 会以确定性的方式将它标记出来。

这些 scanner 运行在实现代码上。BrassCoders 编排的上游工具包括 Bandit、detect-secrets、Pyre/Pysa、Semgrep、ast-grep,以及六个自定义 detector。这些自定义 detector 覆盖 secret 格式模式、隐私与 PII 处理、AI 生成代码中的 phantom API 调用、性能反模式、内容审核信号,以及 JavaScript/TypeScript。即使一个数据库 handler 拥有 100% 的测试覆盖率,BrassCoders 仍会在第一次扫描时标记出 SQL 注入问题。

发布在 /blog/ai-coder-bug-benchmark/ 的一项 benchmark,从 Copilot、Cursor 和 Claude Code 等 AI coding assistant 中选取了 12 个真实 bug,并分别使用 Bandit 和 BrassCoders 进行测试。Bandit 捕获了 12 个 bug 中的 6 个,BrassCoders 则捕获了 11 个。Coverage.py 很可能会显示其中大多数 bug 所在的代码都已被覆盖,因为包含这些 bug 的函数全部都有测试。

Coverage.py 和 BrassCoders 回答的是两个不同的问题。Coverage.py 回答:测试套件执行了哪些代码行?BrassCoders 回答:生产代码中包含哪些安全和正确性模式?一个代码库在第一个问题上可能拿到 95% 的分数,但其中仍然可能存在可被利用的注入漏洞或硬编码凭据。这两个答案并不重叠,所以你需要同时使用二者。

运行 pip install brasscoders,然后运行 brasscoders scan .,即可查看哪些 scanner 会在你的生产代码上触发。它的 OSS core 免费提供,采用 Apache 2.0 许可证,并且不会将任何数据发送到你的机器之外。

如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。

Original source

本文由 AI 翻译整理,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
MCP 工具描述字符串的隐蔽提示注入风险
下一篇
LLM 工具调用的底层实现原理深析

资讯速览

dev.to · AI · 2026-08-04 03:01

AI 评分 8.0 / 10

相关标签

#测试#质量#AI编程

继续阅读

  • OWASP Agent 安全框架:从 LLM 风险到自主 AI 系统
  • MCP 工具描述字符串的隐蔽提示注入风险
  • LLM 工具调用的底层实现原理深析
  • 多视角 AI 审查:三个 Agent 独立评审发现不同问题的实践
  • AI 生成的类型注解如何骗过 mypy