2.6 软件白盒测试
上面介绍的5个测试用例的设计方法大部分都适用于黑盒测试。下面让我们来详细介绍软件白盒测试的一些知识。先来看一下由Main Cohn提出的著名的软件测试金字塔,如图2-14所示。
图2-14 软件测试金字塔
由于白盒测试是单元测试的主要内容,所以白盒测试在整个软件测试过程中很重要。
图2-15 白盒测试的例子
白盒测试覆盖包括语句覆盖、分支覆盖、条件覆盖、分支/条件覆盖、MC/DC(修订的条件/判定)覆盖、路径覆盖、控制流覆盖等,这些是白盒测试技术中基本的概念,将在本节中详细介绍。在介绍之前,看一下本节中将要用到的一个程序,如图2-15所示。
这里包括:
3个语句:S1,S2,S3。
2个判断:M1,M2。
4条路径:L1:ace;L2:abe;L3:acd;L4:abd。
8个条件:T1:x>3,T2:z<10,T3:x=4,T4:y>5,F1:x<=3,F2:j>=10,F3:x<>4,F4:y>=5。
2.6.5 MC/DC(修订的条件/分支软件测试)覆盖测试
MC/DC(修订的条件/分支软件测试)准则是一种实用的软件结构软件测试率软件测试准则,已被广泛应用于软件验证和软件测试过程中。
案例2-19:MC/DC覆盖测试。
condition和decision的概念:
if (A || B && C) {
语句1;
}
Else{
语句2;
}
A,B,C都是一个条件,而(A || B && C)叫一个Decision,如果是条件软件测试,只需两个CASE,就能软件测试,就是让这个decision为True和False各一次,就能达到。即:
- A=True,B=False,C=True。
- A=False,B=True,C=False。
如果是MC/DC,就得4个测试用例,怎么计算呢?
MC/DC覆盖测试在每个判定中的每个条件都曾独立影响判定的结果至少一次(独立影响意思是在其他条件不变的情况下,改变一个条件)。
A || B && C
总结:每个条件对结果都独立起作用。
(1)如果A对结果起作用的话,B必须为False,C必须为True,这样结果就独立受A的值影响。(A||0&&1)->(A||0),(A、B、C取值分别为A=True、B=False、C=True和A=False、B=False、C=True)。
(2)同理,如果B对结果独立起作用,A必须为False,C必须为True,两种情况B为True,False各一个(0||B&&1) (A,B,C取值分别为A=False,B=True,C=True和A=False,B=False,C=True)。
(3)如果C独立对结果起作用,就是让(A ||B) 为True,为了减少用例,上面的用例已经含有这样的用例了,就取A为False,B为True,这样C独立起作用的用例为(0||1&&C)->(1&&C)。(A,B,C取值分别为A=False,B=True,C=True和A=False,B=True,C=False)。
可以看出,每个条件各走了一次True和False,这样3个变量条件就会有6个用例, 但是其中里面有两个是重复的。
- 在1、2情形中均出现A=False,B=False,C=True。
- 在2、3情形中均出现A=False,B=True,C=True。
因此,最后的测试用例为。
- A=True,B=False,C=True。
- A=False,B=False,C=True。
- A=False,B=True,C=True。
- A= False,B=True,C=False。
需要进一步补充说明的是,MC/DC测试的主要目的是为了防止在组合条件表达式中包含副作用(side effect),见以下语句:
if (a()|| b() || c()){ ... }
当b函数或c函数产生副作用时,MC/DC软件测试存在非常大的必要性。
原则上不应在组合条件表达式中调用产生副作用的函数。
2.6.6 路径覆盖测试
路径覆盖的含义是:选取足够多的软件测试数据,使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次)。
路径覆盖率的公式可以表示如下:
路径覆盖率=被执行的路径数量/所有路径数量×100%
图2-16 路径覆盖
案例2-20:路径覆盖(图2-16)测试。
这里存在4条路径,分别为(1,3)、(1,4)、(2,3)、(2,4)。为了达到这些路径,设计测试用例见表2-25。
表2-25 路径覆盖测试用例
a |
b |
覆盖路径 |
1 |
1 |
1、3 |
1 |
0 |
1、4 |
0 |
1 |
2、3 |
0 |
0 |
2、4 |
回看本节开始的例子,设计什么数据可以使路径覆盖达到100%呢?第2.6.2节提到的两组测试用例,第一组测试用例分别执行了路径L4(abd)和L3(acd),第二组测试用例分别执行了路径L2(abe)和L1(ace)。所以,使用这4个测试用例,就可以达到路径覆盖测试100%。
路径覆盖测试用例见表2-26。
表2-26 路径覆盖测试用例
测试用例 |
原子条件 x>3,[J30] z<10 |
M1 x>3 &&z<10 |
原子条件 x=4,[J31] y>5 |
M2 x=4 ||y>5 |
覆盖路径 |
x=4,[J32] y=6,[J33] z=9 |
T1,[J34] T2 |
True |
T3,[J35] T4 |
True |
L4 |
x=4,y=5,z=10 |
T1,F2 |
False |
T3,F4 |
True |
L3 |
x=5,y=4,z=9 |
T1,T2 |
True |
F3,F4 |
False |
L2 |
x=4,y=5,z=10 |
F1,F2 |
False |
F3,F4 |
False |
L1 |
以上6种覆盖率强弱关系如图2-17所示。
图2-17 白盒测试各种覆盖的强度
顾翔凡言:
敏捷具有适用性,即使用了敏捷,也不要做成假敏捷,掌握敏捷的真谛。