看不懂突变改了什么,怎么写测试杀死它?
mutation testing 发现了一个 survivor,但你根本不知道这个 mutation 做了什么。这里有一个分步方法,让你不用先理解 mutant 也能写出正确的测试。
你的 mutation testing 报告里全是 survivor,其中至少有一个你完全看不懂。 工具说它把第 47 行的 换成了 ,或者把整个条件块替换成了 ,又或者变异了一个你根本不知道正在被测试的字符串字面量。你 diff 看了三遍。你还是不明白这个 mutant…
7 posts
mutation testing 发现了一个 survivor,但你根本不知道这个 mutation 做了什么。这里有一个分步方法,让你不用先理解 mutant 也能写出正确的测试。
你的 mutation testing 报告里全是 survivor,其中至少有一个你完全看不懂。 工具说它把第 47 行的 换成了 ,或者把整个条件块替换成了 ,又或者变异了一个你根本不知道正在被测试的字符串字面量。你 diff 看了三遍。你还是不明白这个 mutant…
为什么在整个代码库强制执行单一变异分数是错误的,以及如何根据实际风险设置按模块划分的阈值。
在整个代码库强制执行单一变异分数,是让团队厌恶测试的绝佳方式。 用 PIT 或 Stryker 跑一个典型仓库,你会看到同样的模式:认证模块得 40%,字符串工具类冲到 95%,ORM 层则在 60 多分徘徊。本能反应是设一个全局门槛,比如 70%,堵住所有低于它的 PR。两个冲刺之后,就会有人在 CI…
代码覆盖率告诉你很安全。变异测试告诉你,你的测试大多只是摆设。以下是存活变异体如何暴露这一鸿沟,以及如何弥合它。
你的测试全过了。覆盖率报告显示87%。但你的变异得分是40%,一半的变异体还活着。 这个40%不代表你的代码有毛病。它代表你的测试有毛病。覆盖率衡量的是测试运行期间哪些行被执行了。变异测试衡量的是,如果那些行开始做错事,你的测试会不会发现。40%的变异得分意味着,60%本可以被引入代码的 bug 会大摇大摆地通过…
cargo-mutants 能找出那些只是假装在验证代码的测试。本文介绍变异测试在 Rust 中的工作原理、它能捕捉什么问题,以及编译时间成本是否值得。
你有 100% 的行覆盖率。每个分支都执行到了。每个函数都被调用了。然后有人在定价逻辑里把一个 改成了 ,跑了一遍测试,全部通过。 这不是理论问题。它真实发生在你的测试执行了代码,却没有真正验证行为的时候。覆盖率衡量的是哪些行被执行了,而不是哪些输出被检查了。变异测试通过故意引入小的…
大多数团队不会每次提交都跑完整的变异测试套件。以下是工程团队如何在不破坏构建流水线的情况下,真正把变异测试集成进CI的做法。
如果你的变异测试套件需要跑四个小时,恭喜你。你证实了大家早就怀疑的一件事:你的测试套件存在漏洞。 你不可能每次 push 都到 CI 里跑这个。没有哪个团队会这么干。问题不在于你能否承受每次提交花四小时,而在于你能否承受带着“测试通过但实际上什么也没验证”的代码上线。…
如果你想让 AI-generated code 能在生产环境里站得住,光靠 code review 不够。你需要一套从 type constraints 到 mutation testing 与 runtime containment 的分层安全栈。
AI-generated code 最大的危险,不是它总是错的。 真正危险的是,它经常“看起来已经对得足够可以 merge”。 这正是风险所在。明显有问题的 code 往往会被挡住。真正会进生产的是那种看起来合理、能过几个 happy-path tests、却悄悄削弱关键 boundary 的实现。…
Design by contract、property-based testing、mutation testing、model checking 从来不是坏思路。真正的问题是它们长期需要太多专业判断才能维持,而 AI 正在改变这笔账。
软件工程里有很多方法,你一读就会觉得“这当然应该这么做”。 当然应该用 contracts 明确 function 能接收什么、必须返回什么。当然 tests 不该只写几个人工挑选的例子,而应该验证 properties。当然团队不该把 coverage 当成质量代理,而应该真的去判断 tests 能不能抓到…