news 2026/10/13 4:00:53

当 AI 告诉你「测试全过」时:3 次被拆穿的假警报

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
当 AI 告诉你「测试全过」时:3 次被拆穿的假警报

让 AI Agent 帮你写测试、跑测试,你多半收到过一句令人安心的提示:「全部通过(All Passed)」。但很多时候,事后查验才会发现,这句承诺漏洞百出。

这篇文章记录了三次「全部通过」被无情拆穿的过程。所有的数字和日志都真实存在,未作修改。文章最后,总结了三个针对「假通过」的硬核解法。

(背景提示:事情发生在一台 Windows 测试机上,几个 AI Agent 正分头协作,将一个名叫 Polter 的多 Agent 终端应用移植到 Windows 平台。)


第一次「假摔」:号称 16 个通过,其实 3 个根本没碰到

当时的界面上排布着 17 个标签(Tab)。测试 Agent 写了一段脚本,挨个去点击这 17 个标签的中心点。

一开始,Agent 自信地汇报了战况:

  • 系统播报:17 tabs, 1 mismatches
  • 字面意思:只有 1 个报错,其余 16 个完美通过。

但仅仅四分半钟后,写测试的 Agent 自己推翻了这行读数:真正被有效检验过的,只有 13 个。

标签状态Agent 最初汇报真实情况假警报原因
第 1~13 个成功成功正常点击,没问题。
第 14 个失败成功界面太挤,标签中心点被右侧的「+」按钮盖住了,点错位置了。
第 15~17 个成功未测试坐标已超出屏幕边界,物理上根本点不到,测试函数“闭眼”报了通过。

为什么 15~17 号标签会被标记为通过?因为测试脚本只是去问了代码内部的判定函数,函数闭着眼睛回了一句ok。它看似全绿,其实一个像素都没真正测到。

Agent 留言录:
“报假警报的测试,好歹还会让人看一眼;而报0 mismatches的测试,往往是让代码失去信任的最快方式。”

修复之后,测试结果不再是非黑即白的过与不过,而是变成了三个维度的真实数据:
17 tabs, 13 ok, 0 mismatches, 4 untested


第二次「盲区」:盯着一个永远不会变的像素点

第一次是测试脚本在自欺欺人,第二次则是测试标准定得极其荒谬。

为了测试「窗口拉大时,画面能不能及时跟上」,Agent 制定了如下判定标准:

  • 扩大窗口尺寸。
  • 检查拉大前后,窗口中心点的像素颜色是否发生变化。如果没变,说明画面跟上了。

从数据上看,窗口尺寸从984x631变大到了1224x751,中心点颜色一模一样。测试完美通过!然而,这个测试在 Bug 存在的情况下,安然无恙地「全绿」了一整天。

当天下午,换了一种测量方式后,真相大白:当窗口被拉大时,新增的边缘区域全是黑屏,画面渲染其实失败了。但因为旧画面一直固定在左上角,无论怎么拉大,原本的「中心点」永远都会落在旧画面里。

测试标准测量位置结果缺陷
旧标准 (假绿)固定的窗口「旧中心点」永远通过就像蒙上了眼睛,去验证光的存在,完全看不到边缘的黑屏。
新标准 (真抓)算出「新露出来的边缘区域」,测新区域像素真实报错因为新区域的像素,绝对不可能来自上一帧画面。

第三次「幽灵」:它之所以绿,是因为根本没触发

前两次的测试好歹还在机器上跑了,第三次,在报出「全绿」的那台机器上,根本连跑都没跑过。

当时团队在修一个 Windows 独有的 Bug(子进程输出权限被 AutoRun 配置拦截)。为了防止 Bug 回归,Agent 写了一条测试:让子进程去尝试输出,能输出就是ok。

这条测试在 macOS 开发机上跑,永远是全绿通过。提交代码的 39 分钟后,在 Windows 真机上第一次跑,直接爆红失败。

运行环境测试结果真实原因
macOS (开发机)全绿通过macOS 压根没有 Windows 的 AutoRun 机制,这条容易报错的代码路径连碰都没碰到。
Windows (真机)爆红失败环境触发了拦截机制,真实暴露了 Bug。

Agent 留言录:
“一个专门为了「看机器环境决定的 Bug」而写的测试,在原本就安全的机器上跑出来的绿,什么也证明不了。”


怎么知道自己在被骗?三个现成的解法

总结这几次发现假测试的路径,有一件事非常显眼:没有哪一次,是通过把原来那条绿色的测试再跑一遍来发现问题的。

你要怎么知道一条测试是不是在骗你?Agent 给出了一个极其精准的判别法:
“不要问『这条测试通过了吗?』。你要问:『如果被测的那个东西坏了,这条测试能看得见吗?』”

在当时的开发记录里,这句话最终落地成了三个非常具体的做法,可以直接抄作业:

1. 汇总行必须报三个数

不要只报「通过」和「失败」。没有被触发的代码,绝不能被藏在ok的数字里。

  • 通过 (OK)
  • 不符 (Mismatch/Fail)
  • 没测到 (Untested/Skipped)——三个数加起来,必须等于总数。

2. 「预期为空」的旁边,绑一条「预期非空」

如果你测试的标准是“日志里没有报错”,这可能意味着没报错,但也可能意味着代码压根就没运行!
断言必须有底线:你可以要求没报错,但必须同时断言**“程序确实执行到了这里”**(比如要求某个常规启动日志至少出现一次)。如果没有,一律记作「没测到」。

3. 故意改坏代码,看测试红不红(最硬核)

写完测试后,故意把被测逻辑改错(比如把取点位置写偏,或者强行制造异常)。如果代码明明坏了,测试依然是绿的,说明这个测试根本就是瞎的。每一次主动制造的红,都是为了证明下一次的绿有意义。


下次如果你的 AI Agent 潇洒地告诉你0 failures时,记得接着问它两个数字:
“跳过了几格?有几格根本没跑到?”

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 4:00:10

Linux进程完全指南:原理、状态与故障排查实战

作为后台开发和运维人员,几乎都会遇到这样的场景:线上服务CPU突然飙到100%,进程怎么都杀不掉,或者kill之后端口还被占着,查了半天才发现是僵尸进程。这些问题的根源,都指向同一个东西——Linux进程。进程不…

作者头像 李华
网站建设 2026/10/13 3:59:30

Linux命令速查宝典:高频操作、场景索引与排障实战

1. 为什么我一直想写一份Linux命令速查这些年工作中有一件事印象特别深:组里的新同学入职,第一周几乎天天抱着图形界面点来点去,部署一次测试环境要花一下午。后来我拉他坐下,把他的高频操作一条条换成了Linux命令,他当…

作者头像 李华
网站建设 2026/10/13 3:59:25

生鲜电商App so签名算法逆向:基于unidbg的完整实现

做生鲜电商这类App的接口分析时,总会遇到一个绕不开的坎:核心签名算法被塞进so库里,Java层怎么翻都只能看到一个native方法声明,真正干活的逻辑全在底层。标题里这个“某生鲜电商-unidbg”项目,本质上就是一套完整的so…

作者头像 李华
网站建设 2026/10/13 3:58:52

电商数仓实战:从ODS到ADS的四层精简架构与Trino优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 3:58:34

Simulink仿真验证二阶系统:从传递函数到PID整定与Bode图校验

Simulink 做经典控制理论的仿真验证,是控制工程里绕不开的一件事。学完系统的传递函数、时域响应、PID、Bode 图这些内容,如果只停留在纸面推导,很难真正建立"理论公式和实际系统表现之间的对应感"。这篇文章以一个二阶系统的综合仿…

作者头像 李华