分支(判定)覆盖是设计一定量的测试用例使程序中的每个判断语句的真假分支都得到覆盖,但是分支覆盖不能保证判断语句中每个条件的真、假分支都得到覆盖。
条件覆盖虽然可以覆盖判断语句中每个条件的真、假分支,但可能没有将所有判断语句的真、假分支覆盖全,仍然做不到对程序的 100% 的覆盖。所以,我们需要把分支(判定)和条件覆盖一起进行综合考虑。
分支-条件覆盖,也叫判定-条件覆盖,是指运行代码进行测试时,程序中所有判断语句中的条件取值为真、取值为假的情况和整个判断语句取真分支、假分支的情况都被覆盖到(即,至少被执行过一次)。
栗子
public static int test(int a, int b, int c) {
int result = 0;
if (a == 0 || b > 2) {
result = b - a;
}
if (a > 0 && c > 0) {
result = c * a;
}
return result;
}
第 1 步:分析待测试代码,画出程序的流程图。
第 2 步:分析流程图。
这段代码中有两个判断语句,分别是上图中标识为 ② 和 ③ 的语句,语句 ② 中有两个条件语句,分别为 a == 0 和 b > 2 ;语句 ③ 中也有两个条件,分别为 a > 0 和 c > 0 。
为了使后续的分析过程更加清晰明了,我们先来梳理一下流程图中的判断语句及语句中的条件项
判断语句:
判断语句 | 取值 | 标识 |
---|---|---|
a == 0 or b > 2 | 真 | T1 |
a == 0 or b > 2 | 假 | F1 |
a > 0 and c > 0 | 真 | T2 |
a > 0 and c > 0 | 假 | F2 |
条件:
条件 | 取值 | 标识 |
---|---|---|
a == 0 | 真 | Y1 |
a == 0 | 假 | N1 |
b > 2 | 真 | Y2 |
b > 2 | 假 | N2 |
a > 0 | 真 | Y3 |
a > 0 | 假 | N3 |
c > 0 | 真 | Y4 |
c > 0 | 假 | N4 |
第 3 步:使用分支-条件覆盖法编写测试用例。
根据分支-条件覆盖法的定义,这种方法是将分支覆盖和条件覆盖结合起来,设计一些测试用例,使程序中每个判定语句中的每个条件为真和为假的情况都至少被执行一次,并且每个判断语句本身为真、为假的情况也至少被执行一次。因此,我们可以设计如下表中的测试用例来对程序中的两个判断语句及其四个条件进行覆盖:
测试用例编号 | 输入数据 | 预期结果 | 条件覆盖情况 | 分支覆盖情况 |
---|---|---|---|---|
testcase_01 | a = 0 , b = 5 , c = 0 | result = 5 | Y1、Y2、N3、N4 | T1、F2 |
testcase_02 | a = 5 , b = 1 , c = 3 | result = 15 | N1、N2、Y3、Y4 | F1、T2 |
代码实现
Demo.java
public class Demo {
public static int test(int a, int b, int c) {
int result = 0;
if (a == 0 || b > 2) {
result = b - a;
}
if (a > 0 && c > 0) {
result = c * a;
}
return result;
}
}
DemoTest2.java
import org.junit.Assert;
import org.junit.Test;
public class DemoTest2 {
@Test
public void testDemo01(){
Assert.assertEquals(5, Demo.test(0, 5, 0));
}
@Test
public void testDemo02(){
Assert.assertEquals(15, Demo.test(5, 1, 3));
}
}
通过执行以上两个用例可以实现程序的分支-条件 100% 覆盖。
那么,是不是实现了分支-条件覆盖就代表程序已经被覆盖全面了呢?下图是该程序标识了执行路径的流程图:
从上图中可以看出,这段代码共有四条路径,分别为:路径 1( A - C )、路径 2( A - D )、路径 3 ( B - C )、路径 4( B - D )。通过分析,我们可以知道:测试用例 testcase_01 覆盖的路径是路径 3 ( B - C ),测试用例 testcase_02 覆盖的路径是路径 2( A - D ),路径 1 和路径 4 没有被覆盖到。所以,分支-条件覆盖的覆盖强度仍然不够,如果判断语句中的逻辑运算存在问题可能仍然无法被发现。例如,如果将第一个判断语句 if(a == 0 or b > 2) 中的 or 错写成了 and ,使用这两个测试用例仍然能执行通过,但未检查出程序中的逻辑运算错误。