第5章 白盒与黑盒测试的测试用例设计5.1 覆盖率的概念•覆盖率是用来度量测试完整性的一个手段•逻辑覆盖和功能覆盖• 覆盖率=(至少被执行一次的item数)/item总数5.2 白盒测试的测试用例设计5.2.1 逻辑覆盖逻辑覆盖是以程序内部的逻辑结构为基础的测试用例设计技术,属白盒测试 最彻底 的白盒测试是覆盖程序中的每一条路径,但是由于程序中含有循环,要执行每一条路径是不 可能的因此我们只是希望采用的测试用例覆盖程序内部逻辑的程度尽量高些为了衡量测 试的覆盖程度,需要建立一些作为测试彻底度的定量衡量标准目前常用的覆盖标准是:(1) 语句覆盖;(2) 判定覆盖;(3) 条件覆盖;(4) 判定/条件覆盖;( 5) 条件组合覆盖一、引例图1 是一个被测试的程序流程图,其中有两个判断,每个判断都包含复合条件的逻辑表 达式图1 测试用例程序流程图其源程序是:main(){ float text(float A, float B, float X);if(A>1)&&(B==0)X=X/A;if(A==2)||(X>1)X=X+1;Return(X);} 下面结合引例,介绍按照不同覆盖标准设计测试用例的方法。
二、语句覆盖语句覆盖就是设计若干个测试用例,运行所测的程序,使得每一可执行语句至少执行 一次对引例稍作分析就不难发现,只要设计一个能通过路径 ace 的测试用例即可,程序执行 时就可以遍历流程图的所有框因此,为引例设计满足语句覆盖的测试用例是:[A=2,B=0,X=3]从程序执行过程来看,语句覆盖的方法似乎能够比较全面地检验每一个可执行语句例外:如果在程序中第一个判断的“&”均误写成“I”,或第二个判断的“X>1”均误 写成“X>0”,用上述的测试用例仍可覆盖所有可执行语句,这说明虽然做到了语句覆盖, 但可能发现不了逻辑运算中出现的错误因此这种覆盖实际是一个最弱的覆盖标准三、判定覆盖 判定覆盖就是设计若干个测试用例,使程序中的每个判断至少出现一次“真值”和一 次“假值”,即程序中的每个分支都至少执行一次对本引例,为在语句覆盖的基础上达到判定覆盖标准,要使程序流程能经过路径 acd 和abe或路径ace和abd,为此可设计两个满足要求的测试用例:[A=3,B=0,X=l](沿 acd 执行) [A=2,B=1,X=3] (沿 abe 执行)判定覆盖比语句覆盖严格,因为它使得每一个判断都能获得每一种可能的结果,从而 使每个语句都执行了。
例外:(1)若将第二个判断的“ X>1 ”均误写成“ XV1”,用上述的测试用例仍能得到 相同的结果;(2)上述的测试用例在沿路径abd执行时,并不能检查X的值是否保持一致这表明,只用判定覆盖还不能保证一定能检查出所有的错误 因此,需要更强的逻辑 覆盖标准去检验判断内部条件三、条件覆盖条件覆盖是指利用若干个测试用例,使被测试的程序中,对应每个判断中每个条件的 所有可能情况均至少执行一次在本引例中,共有 4 个判断条件:A>1、B=0、A=2、X>1为达到条件覆盖标准,需要有足够的测试用例以形成:在a点出现有:A>1、AW1、 B=0、BHO的情况,在b点出现有:A=2、AH2、X〉l、XW1的情况出现为此可以设计两 个测试用例以满足这一标准:[A=2,B=0,X=4] (沿 ace 执行)[A=1,B=1,X=1] (沿 abd 执行)例外:[A=1,B=0,X=3] (沿 abd 执行)[A=2,B=1,X=1] (沿 abd 执行)它满足条件覆盖标准,却不满足判定覆盖为解决这种例外,可采用下面介绍的判定 /条件 覆盖标准四、判定/条件覆盖 判定/条件覆盖就是设计足够多的测试用例,使得程序中每个判断条件的所有可能的结 果至少取到一次,又使每次判断的每个分支至少通过一次。
可设计两个满足要求的测试用例:[A=2,B=0,X=4] (沿 ace 执行)[A=1,B=1,X=1] (沿 abd 执行)[A=2,B=1,X=1] (沿 abe 执行)判定/条件覆盖仍有缺陷,因为在程序执行过程中,某些条件掩盖了另一些条件例如 对条件表达式(A>1)&(B=0),取A=l、B=0,此时(A>1)为假,则目标程序不再检查(B=0) 条件了,从而发现不了 B的错误同样对条件表达式(A=2)I(X>1),取A=2,此时(A=2) 为真,则目标程序也不再检查(X>1)条件因此,采用判定/条件覆盖,逻辑表达式中的 错误不一定能测试出来五、 条件组合覆盖解决上述问题的新标准是条件组合覆盖 条件组合覆盖就是设计足够多的测试用例, 使得每个判断的所有可能的条件取值组合至少执行一次对于本引例,按照条件组合覆盖标准,必须使测试情况覆盖 8 种组合结果:① A>1, B=0② A>1,BHO③ AW1, B=0④ AW1, BHO⑤ A=2, X>1⑥ A=2,XW1⑦ AH2, X>1⑧ AH2, XW1其中测试情况⑤、⑥、⑦、⑧是第二个条件语句的条件组合因为X的值在该语句之 前可能要发生变化,所以要通过程序逻辑回溯以便找出相应的输入值。
要覆盖这 8 种条件组合,并不一定需要设计 8 组测试用例,我们可以设计4 个测试用 例就可以满足要求设计的测试用例如下:[A=2,B=0,X=4](沿ace执行,覆盖①和⑤)[A=2,B=1,X=1](沿abe执行,覆盖②和⑥)[A=1,B=0,X=2](沿abd执行,覆盖③和⑦)[A=1,B=1,X=1](沿abd执行,覆盖④和⑧)上述测试用例覆盖了所有条件的可能取值的组合,覆盖了所有判断的可取分支,但还 是漏掉了路径acd,,因此测试还不完全六、 逻辑覆盖举例[例1]试用逻辑覆盖测试法为采用冒泡排序(bubble sorting)法进行数据排序的C程序 设计测试用例本例是一个对k个整数进行升序排序的C程序,采用的算法是冒泡排序其基本步骤 是:(1) 从数组中取出第2个元素;(2) 如果新取出的元素大于等于其前邻元素,则转向第(4)步;(3) 如果新取出的元素小于其前邻元素,则与其前邻元素交换位置;(4) 将新元素与新的前邻元素比较,若仍小于新的前邻元素,则重复第(3)步;(5) 取下一个元素如果数组中元素已取完则结束排序,否则转向第(2)步 下面将给出本例的C程序图2则是排序部分的流程图。
main(){ int a[11],i,j,k,temp;scanf(“%d”,k);printf(“input numbers:\n”);for(i=1;i<=k;i++)scanf(“%d”,&a[i]);printf(“\n”);for(i=2;i<=k;i++){ if(a[i]>=a[i-1]) continue;for(j=i;j<=2;j--){ if(a[j]>=a[j-1] continue; temp=a[j];a[j]=a[j-1];a[j-1]=temp;}}printf(“the sorted numbers:\n”);for(i=1;i<=10;i++)printf(“%d”,a[i]);}设计方法:(1) 采用语句覆盖设计测试用例 对本例稍作分析就不难发现,只要向数组输入先大后小两个数,程序执行时就可以遍 历流程图的所有框因此,为引例设计满足语句覆盖的测试用例是:[a={10,6},k=2] 由于语句覆盖是一个最弱的覆盖标准虽然做到了所有语句的覆盖,但可能发现不了 逻辑运算中出现的错误2) 采用判定覆盖设计测试用例对本例,在语句覆盖的基础上,如果要使程序流程经过路径L1和L2,可设计两个满足 要求的测试用例:[a={10,6,7},k=3] [a={10,6,12},k=3] 或合并成一组测试用例:[a={10,6,12,7},k=4]上述测试用例是在满足条件a[i]>=a[i-l]或a[j]>=a[j-1]的情况下经过路径L1和L2,而未 检查另一个条件a[i]=a[i-1咸a[j]=a[j-1],即使在程序中将两处“>=”都误写成“〉”,测试结 果仍将显示“正常”,使这个错误被掩盖。
因此可将上述测试用例改为:[a={10,6,10},k=3] [a={10,6,6},k=3] 或: [a={10,6,10,6},k=4]则程序将在满足a[i]=a[i-1咸a[j]=a[j-1啲条件下经过路径L1和L2,实现判定覆盖但 结果是将“>=”误写成“>”的错误被掩盖,从而造成更加严重的测试漏洞因此需要更强 的逻辑覆盖标准去检验判断内部条件3) 采用条件覆盖设计测试用例要实现条件覆盖,就必须使被测试的程序中,对应每个判断中每个条件的所有可能情 况均至少执行一次对本例可设计测试用例如下:[a={10,6,12,7},k=4][a={10,6,10,6},k=4](4) 采用其它覆盖设计测试用例在本例中的两个复合条件,其组成条件都不是相互独立的若其中一个条件(如 a[i]>a[i-1])为真,贝I」另一个条件(a[i]=a[i-1])必然为假所以就本例,判定/条件覆盖及条 件组合覆盖都没有实际意义总之,本例应该选择条件覆盖测试方法,以得到较强的查错能力因此,为本例设计的测试用例是:[a={10,6,12,7},k=4][a={10,6,10,6},k=4]5.2.2 基本路径覆盖逻辑覆盖测试主要关注的是程序内部的逻辑结构,最彻底的测试就是覆盖程序中的每 一条路径,但在实际应用中,一个不太复杂的程序,要覆盖的路径数都是一个庞大的数目, 而要执行每一条路径更是不可能的。
因此我们希望通过一定的方法将要覆盖的路径数压缩到 一个有限的范围内,通过合理地选择一组穿过程序的测试路径,以实现达到某种测试度量, 而确保程序中每一个语句都执行一次这种测试方法就是基本路径覆盖法一、控制流图控制流图是用来考察测试路径的有用工具 控制流图是程序控制结构的图形表示,实 际上就是一种简化了的流程图其基本元素是结点和控制流图 3 显示了分别用程序流程图 和控制流图来表示的程序基本控制结构图 3 程序流程图和控制流图的对照图形说明:(1)流程图中的一组顺序处理框,在控制流图中可以被映射成为一个单一结点,如图 4;图 4 合并结点的控制流图(2)若判断中的条件表达式是复合条件时,需要改复合条件为一系列只有单个条件的 判断,如图 5;图 5 分解为简单条件结点的控制流图(3)控制流图关注的是程序中的判断框,而不是顺序执行部分的细节二、路径的选取 所谓路径测试,就是对控制流图中每一条可能的程序执行路径至少测试一次,如果程序 中含有循环,则每个循环至少执行一次路径选取的一般原则是:(1)必须满足逻辑覆盖的最低标准在 IEEE 的测试标准中,语句覆盖是对白盒测试的最低标准,而在 IBM 的测试标准中, 语句覆盖加判定覆盖是对白盒测试的最低标准。
在此我们主张将语句覆盖加判定覆盖作为路 径选取的最低标准图 6 是一程序的控制流图,本程序不带任何循环我们可以先设计覆盖所有点和所有边 的测试路径,然后将上述路径结合起来就可以得到实现路径覆盖的测试路径图6 一个程序的控制流图面给出了满足 3 种不同覆盖要求的测试路径:测试路径覆盖结点/边覆盖标准acd①,②,③,④点覆盖acd,bea,b,c,d,e边。