你的检查是绿的,因为没人问过它能失败的问题

举报
ySimon 发表于 2026/10/03 17:59:57 2026/10/03
【摘要】 一个检查通过了,未必意味着它可靠——也可能是它从没被问过「能不能失败」。本文用真实的变异测试数据说明:只看「形状」的校验会系统性放行语义错误,并给出把这层缺口变成可重复动作的方法。

一个检查通过了,你会松一口气。但"通过"这个词其实有歧义:它可能是"我确认这件事没问题",也可能是"我从没问过它能不能失败"。这两件事在仪表盘上长得一模一样。

一个真实逃逸的校验

配置门禁要做的事很普通:确认每个 key 都在、每个 value 不是空的。

{
  "service": "orders",
  "region": "cn-north-4",
  "replicas": 3,
  "owner": "platform"
}

有人把 "replicas": 3 改成 "replicas": 0。服务从此起不来。门禁放行了。

原因不复杂:门禁检查的是「key 存在」和「value 非空」。0 既存在,又不为空。它测的所有结构属性依然成立。

这类缺口能活下来,恰恰因为它只测形状。任何只看结构的东西,都看不见它。

把"找缺口"变成可重复的动作

靠人眼找这种缺口不现实。但有一件事机器做得很好:变异。

把配置逐行改坏——删一行、清空一个值、把数字改成 0——每改一次就跑一遍你的门禁,看它响不响。

mutants    : 12
caught 11 / 12
mutants the gate let through (1):
  *  blank-value:config.json:4:"replicas":

12 个变异,11 个被拦住,1 个溜过去。溜过去的那个,精确指向一条没有任何东西在测的规则。

同一条规则,用在数字上

门禁之外,同一个问题适用于所有指标。

你有一个健康度分数,它一直是 1.0。它在告诉你系统完美吗?不是。它在告诉你:这个数字从来没被观测到会因不同输入取不同的值。

一个数字,在被观测到会因不同输入取不同值之前,都不是测量。

固定不变的 1.0 不是"满分",是"没测"。一个从没被问过能失败的问题的仪表盘,是另一种形式的静默——而工具存在的意义,是让这种静默变得能被听见。

第二个漏洞:检查是什么时候写的

就算一个检查真的能失败,还有第二个口子:它是什么时候写出来的。

如果检查是等工作做完才写的,写它的人已经知道结果长什么样,就很容易把检查调成"刚好通过"。这不是恶意,是自然。

解法是把检查冻结在运行之前:先写验收条件,hash 锁定,再去干活。干完再改检查?那之后的所有结论作废——可证明地作废,不是靠约定。

还有一层更狠的自检:检查通过之后,把被检查的产物改坏,再跑一遍。如果一个检查在坏输入上依然通过,它从来就不是证据。

$ precheck register
froze 1 commitment(s) at seq=1  sha256=e2d4561aa9f0
$ precheck settle
PASS  the deployment config is valid and safe to ship
$ precheck audit
ran 4 mutation(s) across the declared artefacts
2 check/mutation pair(s) survived -- these prove nothing yet

真实数字

把它指向一个 25 条规则的门禁:175 个变异,78 个溜过,其中 4 个是真缺陷。

4 个里最值得看的一个不是模拟出来的,是设计缺陷:一条规则的触发条件由被检查方自己提供——“如果你声明自己是非交互的,就必须注册”。于是删掉那句声明,要求就消失了。

一个只在你承认有罪时才生效的检查,不是检查。

一个反直觉的忠告

这类工具最容易被误用的地方,是被当成判决器。

跑一遍,输出一堆"存活变异",然后宣布发现了 19 个缺陷——这是撒谎。存活变异是候选,不是缺陷。上面那次跑里,大多数存活变异是无害的(删掉一个 title、删掉一个可选字段)。

一个会喊"19 个缺陷!"的工具,在你第二次核对时就会被你丢掉。所以它该给的是清单,不是判决。

怎么落地

  1. 把你的门禁命令接进来。任何"非零即拒绝"的命令都行:linter、schema 校验、CI 步骤、你自己的 validate.py。
  2. 让它在 CI 里逐行变异、重跑、报告活下来的变异。
  3. 对指标做同一件事:找一个你已经在采集的分数,问它是否曾经取过不同的值。没有,就不是指标。
  4. 把"检查必须写在运行前、且 hash 锁定"变成流程,而不是靠自觉。

零依赖、退出码 0/1,可以直接当它自己的 CI 步骤。

绿是结果,不是证据。真正的问题是:这个绿,有没有可能变成红?

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。