变化的不对称性:为何你的测试方向有误

发布日期:2026-05-09 10:02:45   浏览量 :1
发布日期:2026-05-09 10:02:45  
1

2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家 

变革的不对称性:为何你的测试方向错误

构建通过往往被视为正确性的证明。实际上,它只是一份狭窄的契约。

它并不能证明你的代码是正确的。它只能证明你过去针对当时预期的行为所编写的断言,在今天仍然成立。

当你发起一个拉取请求时,你的单元测试在问:“系统是否仍像以前那样运行?”

而你真正需要回答的问题是不同的:“我刚刚引入的新行为是否安全?”

这两者并非同一回事。而这一差距正是生产环境事故滋生的地方。

错误的问题

问题在于:测试是对过去理解的一个快照。

你的代码变了。你的测试没变。但不知何故,构建状态仍然是绿色的(通过)。

一个保护性子句消失了。没有测试明确覆盖它,因为该保护子句本身就是覆盖率的一部分。一个条件被收窄。一个异常处理器被替换。一个状态转换丢失了一个验证步骤。

测试套件对这些视而不见,因为它从未被要求关注这些事项。它被要求关注的是其他事情。而那些事情仍然运行良好。

证据

这并非理论推测。多项独立研究在所有主流编程语言中都发现了相同的模式。

测试协同演进研究:

一项 2025 年的研究分析了跨越 JavaScript、TypeScript、Java、Python、PHP 和 C# 的 526 个代码仓库。发现:测试与代码的异步演进普遍存在。[1] 早期对 975 个 Java 项目的研究也得出了同样的结论:生产代码经常在没有更新测试的情况下发生变更。[2] 这种现象自至少 2010 年起就有记录。[3]

Chromium 持续集成研究:

研究人员分析了 14,000 次提交中的 150 万次测试执行。结果:即使精度高达 99.2%,现代的 flakiness(不稳定测试)检测仍然导致 76.2% 的真实回归缺陷被遗漏。[4] 这并不是因为缺少测试。而是因为现有的测试被静默了。

真实案例 - Django 6.0:

querystring 模板标签的一次重构中,引入了一个循环,该循环在标准字典上运行良好,但却 silently(无声地)破坏了 QueryDict 实例。现有测试通过了。这个缺陷随版本发布。它仅被一个针对性的渲染输出测试捕获,而没有人想到要定期运行该测试。[5]

数据:

在对 57 个开源 .NET 代码仓库中的 598 个拉取请求的分析中,71% 未修改测试文件的拉取请求包含至少一个行为风险指标。[6] 这不是特例。这是常态。

时间机器问题

每一次差异比较都是一台单向行驶的时间机器。

断言停留在它们被编写时的位置。其下的代码则向前迈进。

// 之前:隐式契约
if (user == null) return; 
Process(user.Name);

// 之后:契约被破坏,测试未察觉
Process(user.Name);

保护子句一直存在。正因为它一直存在,n

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
支持 反馈 订阅 数据
回到顶部