7.6.4 白盒测试
白盒测试把程序内部结构打开来看。它不满足于“输入输出看起来对”,而是关心代码里的语句是否执行过、判定的真/假方向是否走过、条件取值是否覆盖、路径是否充分。
白盒测试看什么
黑盒测试从需求出发,白盒测试从代码结构出发。白盒测试常用于单元测试、关键算法测试和复杂逻辑验证。
flowchart TD
C["源代码/控制流图"] --> S["语句"]
C --> D["判定节点"]
C --> K["条件表达式"]
C --> P["执行路径"]
S --> SC["语句覆盖"]
D --> DC["判定覆盖"]
K --> CC["条件覆盖/条件组合覆盖"]
P --> PC["路径覆盖/基本路径测试"]语句覆盖
语句覆盖要求每条可执行语句至少执行一次。它是最弱的逻辑覆盖,因为一个测试用例可能只让判定走一个方向,却让所有可见语句都执行到了。
if (x > 0) {
y = y + 1
}
z = y * 2如果只用 x = 1 测试,两个赋值语句都执行过,但 x <= 0 的分支没有被验证。语句覆盖不能保证判定的真假方向都被测到。
判定覆盖
判定覆盖也叫分支覆盖,要求每个判定的真、假结果至少出现一次。一个 if 至少要让条件为真一次、为假一次。
| 判定 | 用例要求 |
|---|---|
x > 0 | 至少一次为真,至少一次为假 |
a && b | 整个表达式至少一次为真,至少一次为假 |
while (i < n) | 循环条件进入和退出都应被考虑 |
判定覆盖比语句覆盖强,但仍可能漏掉复合条件内部的取值组合。
条件覆盖
条件覆盖关注判定表达式中的每个基本条件。每个条件都要至少取到真和假。
以 (X >= 0) && (Y <= 5) 为例,有两个基本条件:
| 用例 | X | Y | 条件 A: X >= 0 | 条件 B: Y <= 5 | 整体判定 |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 真 | 真 | 真 |
| 2 | 1 | 6 | 真 | 假 | 假 |
| 3 | -1 | 1 | 假 | 真 | 假 |
| 4 | -1 | 6 | 假 | 假 | 假 |
只用用例 2 和 3,可以让 A、B 都分别出现真和假,因此满足条件覆盖;但整体判定结果都是假,不满足判定覆盖。反过来,只用用例 1 和 4,判定结果有真有假,条件也都有真有假;但这只是这个例子的情况,不能机械认为二者总能相互推出。
判定/条件覆盖
判定/条件覆盖要求同时满足:
- 每个判定结果至少为真一次、为假一次。
- 每个基本条件至少为真一次、为假一次。
它比单纯判定覆盖或单纯条件覆盖更强,但仍不一定覆盖所有条件组合。例如 A && B 有 4 种组合,判定/条件覆盖可能只覆盖其中 2 种。
条件组合覆盖
条件组合覆盖要求一个判定中所有基本条件的取值组合都至少出现一次。若有
| 条件数 | 组合数量 |
|---|---|
| 1 | |
| 2 | |
| 3 | |
| 4 |
条件组合覆盖更充分,但成本增长很快。它适合关键逻辑,不适合无差别套到所有代码上。
路径覆盖与基本路径测试
路径覆盖要求覆盖程序中可能的执行路径。它比只看单个判定更关注“判定之间如何串起来”。如果程序有循环,完整路径数量可能非常大甚至不可穷尽,因此实际常用基本路径测试:根据 McCabe 环路复杂度选择一组线性独立路径。
| 覆盖准则 | 关注对象 | 强度理解 |
|---|---|---|
| 语句覆盖 | 每条语句是否执行 | 最弱,容易漏分支 |
| 判定覆盖 | 每个判定真假结果 | 覆盖分支方向 |
| 条件覆盖 | 每个基本条件真假取值 | 覆盖条件取值 |
| 判定/条件覆盖 | 判定结果 + 条件取值 | 同时约束两者 |
| 条件组合覆盖 | 条件取值组合 | 对复合条件更充分 |
| 路径覆盖 | 完整执行路径 | 最充分但成本最高 |
循环测试
循环是白盒测试的重要风险点。循环错误常出现在 0 次、1 次、边界次数、最大次数和退出条件上。
| 循环场景 | 应考虑的用例 |
|---|---|
| 可能不进入循环 | 0 次循环 |
| 最小正常执行 | 1 次循环 |
| 普通情况 | 多次循环 |
| 边界限制 | 最大次数、最大次数 + 1 |
| 嵌套循环 | 外层/内层边界组合 |
考试里循环测试不一定单独大题出现,但它与路径覆盖、McCabe 复杂度关系密切。
容易混淆的关系
| 关系 | 正确说法 |
|---|---|
| 语句覆盖与判定覆盖 | 判定覆盖通常能覆盖更多分支,语句覆盖不保证判定真假都出现 |
| 判定覆盖与条件覆盖 | 二者关注点不同,不能简单互相推出 |
| 条件组合覆盖与条件覆盖 | 条件组合覆盖通常强于条件覆盖 |
| 路径覆盖与穷尽测试 | 路径覆盖已很强,但有循环时完整路径可能不可穷尽 |
| 基本路径测试与 McCabe | 基本路径数通常等于 McCabe 环路复杂度 |
例题
本节小结
白盒测试的核心是覆盖程序内部逻辑。语句覆盖最弱,判定覆盖看分支方向,条件覆盖看基本条件取值,判定/条件覆盖同时约束两者,条件组合覆盖覆盖组合,路径覆盖关注完整执行路线。做题时要先判断题目说的是“语句、判定、条件、组合还是路径”。