软件测试理论介绍:一文讲清白盒测试中的那些代码覆盖率:语句、判定、条件、MCDC等


前言

白盒测试中的代码覆盖率是用来度量测试完整性的一种指标。它基于程序的内部结构,关注程序内部的逻辑路径和代码执行情况,是评价软件测试质量的重要手段之一。
常用的白盒测试覆盖率主要包括以下几种类型:语句覆盖、判定(分支)覆盖、条件覆盖、判定-条件覆盖、条件组合覆盖、修正条件判定覆盖(MCDC)等。
其中最常用的当属:语句覆盖、判定(分支)覆盖和修正条件判定覆盖(MCDC),如下图:
在这里插入图片描述


示例代码

if (A || (B && C) )
{
	// do something
}

一、语句覆盖(Statement Coverage)

语句覆盖又称行覆盖、段覆盖、基本块覆盖等。
定义:在测试时,运行被测程序后,程序中被执行到的可执行语句的比率。
计算公式:语句覆盖率 =(至少被执行一次的语句数量)/(可执行的语句总数)× 100%。
特点:语句覆盖是最基础的一种覆盖方式,可以检验每个可执行语句,但即使语句覆盖率达到了100%,也不能保证发现所有的逻辑错误。
以上述示例为例,只需要以下1个测试用例即可满足语句覆盖100%的要求:
测试用例1:A=TRUE, B=FLASE, C=FALSE

二、判定覆盖(Decision Coverage)/ 分支覆盖(Branch Coverage)

判定覆盖,又称分支覆盖、决策覆盖。
定义:在测试时,运行被测程序后,程序中所有判断语句的取真分支和取假分支被执行到的比率。
计算公式:判定覆盖率 =(判定结果被评价的次数)/(判定结果的总数)× 100%。
特点:若判定覆盖达到100%,则语句覆盖必为100%,但不能确保每个组合条件都分别覆盖到真/假情况,所以同样可能存在逻辑错误未被发现。
以上述示例为例,只需要以下2个测试用例即可满足判定覆盖100%的要求:
测试用例1:A=TRUE, B=FLASE, C=FALSE
测试用例2:A=FLASE, B=FLASE, C=FALSE
用例说明:可以发现这两个测试用例并没有分别覆盖到A、B、C三个条件的真/假。

三、条件覆盖(Condition Coverage)

定义:在测试时,运行被测程序后,所有判断语句中每个条件的可能取值(真值和假值)出现过的比率。
计算公式:条件覆盖率 =(条件操作数值至少被评价一次的数量)/(条件操作数值的总数)× 100%。
特点:覆盖条件的测试用例不一定覆盖判定,即可能满足条件覆盖但不满足判定覆盖。
以上述示例为例,只需要以下2个测试用例即可满足条件覆盖100%的要求:
测试用例1:A=TRUE, B=FLASE, C=FALSE
测试用例2:A=FLASE, B=TRUE, C=TRUE
用例说明:可以发现这两个测试用例并没有分别覆盖到整体条件判定结果的真/假。

四、判定-条件覆盖(Decision Condition Coverage)

定义:在测试时,运行被测程序后,程序中所有判断语句中每个条件的所有可能值(为真为假)和每个判断本身的判定结果(为真为假)出现的比率。
计算公式:判定-条件覆盖率 =(条件操作数值或判定结果至少被评价一次的数量)/(条件操作数值总数+判定结果总数)× 100%。
特点:判定-条件覆盖率实际上是判定覆盖率和条件覆盖率的组合,但采用判定-条件覆盖,逻辑表达式中的错误不一定能够查得出来。
以上述示例为例,只需要以下2个测试用例即可满足判定-条件覆盖100%的要求:
测试用例1:A=FLASE, B=FLASE, C=FALSE
测试用例2:A=TRUE, B=TRUE, C=TRUE
用例说明:可以发现这两个测试用例并没有覆盖到所有判断条件的组合情况。

五、条件组合覆盖(Condition Combination Coverage)

定义:在测试时,运行被测程序后,所有语句中原子条件所有的可能的取值结果组合出现过的比率。
计算公式:条件组合覆盖率 =(至少被执行一次的条件组合)/(总的可能的条件组合数)× 100%。
特点:若条件组合覆盖率为100%,则语句覆盖率、判定覆盖率、条件覆盖率和判定-条件覆盖率必为100%。
以上述示例为例,需要以下8个测试用例才能满足条件组合覆盖100%的要求:
测试用例1:A=FALSE, B=FALSE, C=FALSE
测试用例2:A=TRUE, B=FALSE, C=FALSE
测试用例3:A=FASLE, B=TRUE, C=FALSE
测试用例4:A=FASLE, B=FASLE, C=TRUE
测试用例5:A=TRUE, B=TRUE, C=FALSE
测试用例6:A=FASLE, B=TRUE, C=TRUE
测试用例7:A=TRUE, B=FALSE, C=TRUE
测试用例8:A=TRUE, B=TRUE, C=TRUE
用例说明:遍历所有的条件组合会使测试用例的数量呈指数级增长,导致测试工作量巨大,这与现实中紧缺的测试资源是相违背的。结合实际的测试需求,加上代码中逻辑组合条件的短路原理,其实有些条件组合的测试用例实际是无意义的。

六、修正条件判定覆盖(Modified Condition Decision Coverage)

MCDC覆盖源于DO-178C等适航认证标准,是民用航空电子软件开发和适航认证过程中的重要测试要求,现已广泛应用于各个行业的关键、重要等级的软件白盒测试中。
定义:MCDC覆盖要求程序中的每个判定中的每个条件都要独立地影响判定结果,并且每个判定和每个条件都要至少取到一次所有可能的结果。
特点:MCDC覆盖强调条件之间的独立性,即每个条件都要能够独立地影响判定结果。这有助于发现那些由于条件间依赖关系导致的错误。相比条件组合覆盖等其他高级覆盖策略,MCDC覆盖能够在保证较高覆盖度的同时减少测试用例的数量。
以上述示例为例,只需要以下4个测试用例即可满足MCDC覆盖100%的要求:
测试用例1:A=FASLE, B=FASLE, C=TRUE
测试用例2:A=TRUE, B=FALSE, C=TRUE
测试用例3:A=FASLE, B=TRUE, C=TRUE
测试用例4:A=FASLE, B=TRUE, C=FALSE
用例说明:对于一个由多个条件组合形成的判定语句,满足其MCDC覆盖100%的最少测试用例个数=各个判断条件的总数+1


总结

代码覆盖率作为白盒测试中的一个关键指标,能够帮助开发人员和测试人员了解测试的覆盖面和测试的质量,并为进一步的测试提供指导。通过代码覆盖率数据,可以检测测试是否充分,分析测试的弱点在哪些方面,从而指导设计能够增加覆盖率的测试用例,有效提高测试质量。
在实际白盒测试中,测试人员通常会根据程序的复杂性和测试需求,选择适当的覆盖率类型进行测试。同时,需要注意的是,即使达到了100%的某种覆盖率,也不能保证程序的完全正确性,因为测试覆盖率只是测试完整性的一个度量手段,而不是保证程序无错误的充分条件。

### 累加计算程序中的分支覆盖和条件覆盖测试 在累加计算程序中实现分支覆盖和条件覆盖的测试,可以通过工具 `gcov` 进行辅助分析。以下是关于如何设计测试用例以及利用工具完成覆盖率统计的具体说明。 #### 设计测试用例 为了达到分支覆盖和条件覆盖的目标,需要针对代码中的每一条路径进行充分验证。假设存在如下简单的累加函数: ```c int sum(int a, int b) { if (a > 0 && b > 0) { // 条件表达式 return a + b; } else if (a < 0 || b < 0) { // 另一条件表达式 return -1; // 错误处理 } return 0; // 默认返回值 } ``` 对于上述代码片段,可以观察到以下几点: - **条件覆盖**:需要确保每个布尔子句都被评估为真或假至少一次[^1]。 - **分支覆盖**:需要确保每个可能的控制流路径被触发至少一次。 因此,应构建以下输入组合来满足覆盖需求: 1. 输入 `(a=1, b=1)` 能够使第一个条件 (`a > 0 && b > 0`) 的两个部分均成立。 2. 输入 `(a=-1, b=1)` 或 `(a=1, b=-1)` 能够使第二个条件 (`a < 0 || b < 0`) 成立。 3. 输入 `(a=0, b=0)` 能够进入默认分支并返回零。 这些测试用例的设计能够有效检测所有潜在路径及其对应的布尔判断行为。 #### 使用 gcov 工具 通过编译器选项 `-fprofile-arcs -ftest-coverage` 编译源文件后运行程序,并生成 `.gcda` 和 `.gcno` 文件用于后续分析。之后调用 `gcov` 命令即可获得详细的覆盖率报告。具体操作流程如下所示: ```bash gcc -fprofile-arcs -ftest-coverage example.c -o example ./example # 执行带有不同参数的多次运行以激活全部路径 gcov example.c ``` 生成的结果会显示哪些分支被执行过(`branches taken at least once`)以及未执行的部分[`branches not executed`]。特别需要注意的是逻辑运算符短路特性的影响——即当遇到首个决定性的结果时停止进一步求值的行为可能会导致某些子句无法实际参与计算。 #### 注意事项 由于 C 语言支持逻辑运算符短路机制,在编写涉及复杂多层嵌套或者多个连续比较项构成的大规模条件语句时要格外小心。这可能导致即使理论上应该有机会经历每一个单独的小判定单元却因为前面已经得出结论而跳过了后面的内容。这种情况下单纯依靠增加更多样化的数据样本未必能完全解决问题;有时还需要重构原始算法结构以便更好地暴露隐藏起来的状态转移环节给自动化度量手段捕捉得到。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式软件测试开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值