测试报告里有两个容易被放在一起看的数字:覆盖率和通过率。一次订单处理实验中,前者接近满分,后者却清楚地留下了失败。这两个结果同时成立,也各自有用。
从一条基线测试开始
实验围绕订单处理逻辑展开,包括商品数量、库存、优惠券、会员优惠和地址校验。最初只有一条测试,运行结果为 1 passed。
覆盖报告统计了 50 条语句,其中 12 条没有执行到,语句覆盖率是 76%。这一条通过的测试说明一个具体输入符合预期,却无法回答其他分支会怎样。
我保留了业务实现和原测试,再补充 43 条用例。扩展后的结果是:
| 阶段 | 测试结果 | 未覆盖语句 | 语句覆盖率 |
|---|---|---|---|
| 基线 | 1 passed | 12 / 50 | 76% |
| 扩展 | 37 passed,7 failed | 1 / 50 | 98% |
这是 2026 年 10 月那次实验的记录。它最有价值的部分,是两个数字之间的张力:执行到了更多代码,同时观察到了更多不符合预期的行为。
执行过,不代表算对了
覆盖率关心某段代码是否被执行。断言关心这次执行的结果是否满足预期。
假设某条分支确实被执行了,但它把会员折扣覆盖在优惠券之上,而需求要求的是另一种组合顺序。这条语句仍然会计入覆盖率;只有检查最终金额的断言,才会暴露行为上的差别。
因此,增加测试不只是绕过每个 if。还要问:同一个分支,什么输入会揭示计算错误、类型边界或组合规则的问题?
七个失败,整理成六类问题
实验记录把失败整理为六类:
- 百分比优惠券在单条目场景中的限制。
- 会员优惠与优惠券之间的覆盖关系。
- 布尔值被当成商品数量接收。
- 同一商品重复出现时,累计数量超过库存。
- 畸形条目触发解包异常。
- 地址类型异常时的处理。
它们也提醒我,把失败报告写清楚需要回到需求。已明确规定的金额规则可以直接检查;额外加入的健壮性预期,需要说明依据。不能只因为一个断言失败,就把它无条件写成产品缺陷。
为什么停在 98%
剩下的一条语句是负金额保护。在当时固定的商品数据、券值和会员规则下,不使用 Mock 或修改数据库,就无法构造出进入这条保护分支的输入。
这时应记录“在当前实验约束下不可达”,并解释原因。为了把数字变成 100% 而改变前提,会把另一个实验的问题混进来。
这次实验留下的方法
我会把测试结果分成三层看:
- 到达范围:哪些语句或分支执行过,哪些还没覆盖。
- 行为判断:断言验证了什么,有没有只检查“运行没报错”。
- 需求依据:预期来自明确要求,还是为了探索边界而额外提出的假设。
覆盖率帮助发现盲区,失败用例帮助发现差异,而需求决定该如何解释这些差异。把三者一起看,报告才有下一步。
这篇笔记整理自本人的订单处理白盒测试实验。表中数字保留当时结果,未把失败测试改写成通过。
记于 2026-11-05 · 2026-11-05 更新