在软件测试的白盒测试方法里,有几种重要的逻辑覆盖标准
语句覆盖(Statement Coverage)
- 定义:运行测试用例后,程序中被执行到的可执行语句的比率。
- 特点:这是最基础的覆盖方式,不过即便语句覆盖率达到 100%,也可能存在逻辑错误未被发现的情况。
判定覆盖(Decision Coverage)
- 别称:分支覆盖(Branch Coverage)。
- 定义:运行测试用例后,程序中每个判定的取真分支和取假分支至少经历一次。
- 计算公式:判定覆盖率 =(判定结果被评价的次数)/(判定结果的总数)×100%。
- 特点:判定覆盖比语句覆盖更严格,因为每个判定的真假分支都要被覆盖到。
条件覆盖(Condition Coverage)
- 定义:运行测试用例后,使每个判定中的每个条件的可能取值至少满足一次。
- 特点:条件覆盖关注判定中每个条件的各种可能情况,但它不能保证判定分支都被覆盖。
判定 - 条件覆盖(Decision - Condition Coverage)
- 定义:运行测试用例后,同时满足判定覆盖和条件覆盖的要求,也就是每个判定的所有可能结果至少出现一次,并且每个判定中的每个条件的可能取值也至少出现一次。
- 特点:该覆盖方式综合了判定覆盖和条件覆盖的优势,但可能会遗漏某些条件组合情况。
条件组合覆盖(Condition Combination Coverage)
- 别称:多条件覆盖(Multiple Condition Coverage)。
- 定义:运行测试用例后,使得每个判定中条件的各种可能组合都至少出现一次。
- 特点:这是最严格的覆盖标准,能发现程序中的多种逻辑错误,但随着条件数量的增加,所需的测试用例数量会急剧上升。
示例对比
假设有这样一个判定:if (A > 1 && B < 0)
,我们来看看不同覆盖标准的测试用例设计。
覆盖标准 | 测试用例(A, B) | 覆盖情况 |
---|---|---|
语句覆盖 | (2, -1) | 执行判定为真的分支 |
判定覆盖 | (2, -1)、(0, 1) | 判定分别取真和取假 |
条件覆盖 | (2, 1)、(0, -1) | 条件 A>1(真、假),条件 B<0(真、假) |
判定 - 条件覆盖 | (2, -1)、(0, 1) | 判定取真(A>1 为真,B<0 为真),判定取假(A>1 为假,B<0 为假) |
条件组合覆盖 | (2, -1)、(2, 1)、(0, -1)、(0, 1) | 组合 1(A>1 为真,B<0 为真),组合 2(A>1 为真,B<0 为假),组合 3(A>1 为假,B<0 为真),组合 4(A>1 为假,B<0 为假) |
覆盖强度对比
条件组合覆盖>判定 - 条件覆盖>条件覆盖>判定覆盖>语句覆盖。通常情况下,覆盖强度越高,测试的全面性越好,但测试的成本也会随之增加。在实际的测试工作中,需要根据项目的需求和风险来选择合适的覆盖标准。
以下是一个 C 语言示例,展示了五种覆盖标准的区别以及它们无法发现的潜在问题:
#include <stdio.h>
int main() {
int A = 2, B = -1; // 测试用例输入
int result = 0;
// 判定条件:(A > 1) && (B < 0)
if (A > 1 && B < 0) {
result = 1; // 路径1
} else {
result = 0; // 路径2
}
// 第二个判定:嵌套条件
if (A == 2 || B > -2) {
result *= 2; // 路径3
} else {
result *= 3; // 路径4
}
printf("Result: %d\n", result);
return 0;
}
覆盖标准对比及盲区分析
1. 语句覆盖(Statement Coverage)
- 测试用例:
A=2, B=-1
- 覆盖路径:1 → 3
- 覆盖率:100%(所有语句均执行)
- 无法发现的问题:
if (A > 1 && B < 0)
中&&
误写为||
- 第二个判定条件
A == 2
误写为A = 2
(赋值而非比较) - 路径 2 和路径 4 的逻辑错误
2. 判定覆盖(Decision Coverage)
- 测试用例:
- TC1:
A=2, B=-1
(覆盖真分支) - TC2:
A=0, B=1
(覆盖假分支)
- TC1:
- 覆盖路径:1 → 3 和 2 → 4
- 覆盖率:100%(所有判定分支均执行)
- 无法发现的问题:
- 条件
B < 0
误写为B > 0
(仍能通过真假分支覆盖) - 条件组合错误(如
A > 1 || B < 0
被误写为A > 1 && B < 0
)
- 条件
3. 条件覆盖(Condition Coverage)
- 测试用例:
- TC1:
A=2, B=1
(覆盖A>1为真
、B<0为假
) - TC2:
A=0, B=-1
(覆盖A>1为假
、B<0为真
)
- TC1:
- 覆盖路径:2 → 3(两次测试用例均执行此路径)
- 覆盖率:条件覆盖率 100%,但判定覆盖率仅 50%(假分支未覆盖)
- 无法发现的问题:
- 第二个判定
A == 2 || B > -2
的逻辑错误 - 路径 4 的代码未执行(如
result *= 3
中的错误)
- 第二个判定
4. 判定 - 条件覆盖(Decision - Condition Coverage)
- 测试用例:
- TC1:
A=2, B=-1
(覆盖判定真,条件均为真) - TC2:
A=0, B=1
(覆盖判定假,条件均为假)
- TC1:
- 覆盖路径:1 → 3 和 2 → 4
- 覆盖率:判定和条件覆盖率均为 100%
- 无法发现的问题:
- 条件组合错误(如
A > 1 && B < 0
中&&
被误写为||
,但测试用例仍能通过)
- 条件组合错误(如
5. 条件组合覆盖(Condition Combination Coverage)
- 测试用例:
- TC1:
A=2, B=-1
(A>1 为真,B<0 为真) - TC2:
A=2, B=1
(A>1 为真,B<0 为假) - TC3:
A=0, B=-1
(A>1 为假,B<0 为真) - TC4:
A=0, B=1
(A>1 为假,B<0 为假)
- TC1:
- 覆盖路径:1 → 3、2 → 3、2 → 3、2 → 4
- 覆盖率:条件组合覆盖率 100%
- 无法发现的问题:
- 第二个判定
A == 2 || B > -2
中的运算符优先级错误 - 条件组合覆盖无法发现控制流之外的错误(如
result *= 2
应改为result += 2
)
- 第二个判定
关键区别总结
覆盖标准 | 关注点 | 测试用例数量 | 示例未覆盖问题 |
---|---|---|---|
语句覆盖 | 每条语句至少执行一次 | 1 | 判定条件错误、分支逻辑错误 |
判定覆盖 | 每个判定的真假分支各执行一次 | 2 | 条件内部错误、条件组合错误 |
条件覆盖 | 每个条件的真假值各出现一次 | 2 | 判定整体逻辑错误、未覆盖所有分支 |
判定 - 条件覆盖 | 判定和条件均满足覆盖要求 | 2 | 条件组合错误 |
条件组合覆盖 | 所有条件组合至少出现一次 | 4 | 控制流之外的计算逻辑错误 |
实际应用建议
- 语句覆盖:适用于初步测试或简单代码,但漏检率高。
- 判定覆盖:覆盖基本分支逻辑,是最常用的标准之一。
- 条件覆盖:补充判定覆盖的不足,但需注意可能遗漏分支。
- 判定 - 条件覆盖:平衡覆盖率和成本,但无法发现条件组合错误。
- 条件组合覆盖:全面覆盖逻辑,但测试用例数量随条件数呈指数级增长(n 个条件需 2ⁿ个用例)。
在实际项目中,通常结合多种覆盖标准以降低测试成本并提高缺陷发现率。