白盒与黑盒测试的测试用例设计.docx
《白盒与黑盒测试的测试用例设计.docx》由会员分享,可在线阅读,更多相关《白盒与黑盒测试的测试用例设计.docx(27页珍藏版)》请在冰点文库上搜索。
![白盒与黑盒测试的测试用例设计.docx](https://file1.bingdoc.com/fileroot1/2023-5/29/6d01a76e-67c0-4623-9272-9cd20cf1b5b2/6d01a76e-67c0-4623-9272-9cd20cf1b5b21.gif)
白盒与黑盒测试的测试用例设计
第5章白盒与黑盒测试的测试用例设计
5.1覆盖率的概念
覆盖率是用来度量测试完整性的一个手段
逻辑覆盖和功能覆盖
覆盖率=(至少被执行一次的item数)/item总数
5.2白盒测试的测试用例设计
5.2.1逻辑覆盖
逻辑覆盖是以程序内部的逻辑结构为基础的测试用例设计技术,属白盒测试。
最彻底
的白盒测试是覆盖程序中的每一条路径,但是由于程序中含有循环,要执行每一条路径是不
可能的。
因此我们只是希望采用的测试用例覆盖程序内部逻辑的程度尽量高些。
为了衡量测
试的覆盖程度,需要建立一些作为测试彻底度的定量衡量标准。
目前常用的覆盖标准是:
(1)
语句覆盖;
(2)
判定覆盖;
(3)
条件覆盖;
(4)
判定/条件覆盖;
(5)
条件组合覆盖。
一、引例
图1是-
一个被测试的程序流程图,其中有两个判断,每个判断都包含复合条件的逻辑表
达式。
图1测试用例程序流程图
其源程序是:
main()
{floattext(floatA,floatB,floatX);
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]
从程序执行过程来看,语句覆盖的方法似乎能够比较全面地检验每一个可执行语句。
例外:
如果在程序中第一个判断的“&”均误写成“|”,或第二个判断的“X>1”均误
写成“X>0”,用上述的测试用例仍可覆盖所有可执行语句,这说明虽然做到了语句覆盖,但可能发现不了逻辑运算中出现的错误。
因此这种覆盖实际是一个最弱的覆盖标准。
三、判定覆盖
判定覆盖就是设计若干个测试用例,使程序中的每个判断至少出现一次“真值”和一次“假值”,即程序中的每个分支都至少执行一次。
对本引例,为在语句覆盖的基础上达到判定覆盖标准,要使程序流程能经过路径acd
和abe或路径ace和abd,为此可设计两个满足要求的测试用例:
[A=3,B=0,X=1](沿acd执行)
[A=2,B=1,X=3](沿abe执行)
判定覆盖比语句覆盖严格,因为它使得每一个判断都能获得每一种可能的结果,从而使每个语句都执行了。
例外:
(1)若将第二个判断的“X>1”均误写成“X<1”,用上述的测试用例仍能得到相同的结果;
(2)上述的测试用例在沿路径abd执行时,并不能检查X的值是否保持一致。
这表明,只用判定覆盖还不能保证一定能检查出所有的错误。
因此,需要更强的逻辑
覆盖标准去检验判断内部条件。
三、条件覆盖
条件覆盖是指利用若干个测试用例,使被测试的程序中,对应每个判断中每个条件的所有可能情况均至少执行一次。
在本引例中,共有4个判断条件:
A>1、B=0、A=2、X>1
为达到条件覆盖标准,需要有足够的测试用例以形成:
在a点出现有:
A>1、Aw1、
B=0、B丰0的情况,在b点出现有:
A=2、AM2、X>1、X<1的情况出现。
为此可以设计两个测试用例以满足这一标准:
[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=1、B=0,此时(A>1)为假,则目标程序不再检查(B=0)条件了,从而发现不了B的错误。
同样对条件表达式(A=2)|(X>1),取A=2,此时(A=2)为真,则目标程序也不再检查(X>1)条件。
因此,采用判定/条件覆盖,逻辑表达式中的
错误不一定能测试出来。
五、条件组合覆盖
解决上述问题的新标准是条件组合覆盖。
条件组合覆盖就是设计足够多的测试用例,
使得每个判断的所有可能的条件取值组合至少执行一次。
对于本引例,按照条件组合覆盖标准,必须使测试情况覆盖8种组合结果:
①
A>1,
B=0
②
A>1,
B工0
③
Aw1,
B=0
④
Aw1,
BM0
⑤
A=2,
X>1
⑥
A=2,
Xw1
⑦
A工2,
X>1
⑧
A工2,
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]试用逻辑覆盖测试法为采用冒泡排序(bubblesorting)法进行数据排序的C程序
设计测试用例。
本例是一个对k个整数进行升序排序的C程序,采用的算法是冒泡排序。
其基本步骤
是:
(1)从数组中取出第2个元素;
(2)如果新取出的元素大于等于其前邻元素,则转向第(4)步;
(3)如果新取出的元素小于其前邻元素,则与其前邻元素交换位置;
(4)将新元素与新的前邻元素比较,若仍小于新的前邻元素,则重复第(3)步;
(5)取下一个元素。
如果数组中元素已取完则结束排序,否则转向第
(2)步。
下面将给出本例的C程序。
图2则是排序部分的流程图。
main()
{inta[11],i,j,k,temp;
scanf(“%d',k);
printf(“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(“thesortednumbers”);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-1]或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])为真,则另一个条件(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是一程序的控制流图,本程序不带任何循环。
我们可以先设计覆盖所有点和所有边的测试路径,然后将上述路径结合起来就可以得到实现路径覆盖的测试路径。
选取零次循环的路径;
对循环控制变量指定为负数;
一次通过循环;
典型的循环次数;
循环次数为N-1;
循环次数为N+1。
②嵌套循环
从最深层的循环开始,设定所有外层循环取它的最小值;
测试最小值、最小值+1、最小值-1、典型值、最大值-1、最大值+1、最大值;设定内循环在典型值处,按前一规则测试外层循环,直到覆盖所有循环。
(3)选取最简单的、具有一定功能含义的路径。
(4)由简到繁,若有可能,先考虑不含循环的测试路径,然后补充对循环的测试
(5)尽可能选取短路径;
(6)选取没有明显功能含义的路径,此时要研究这样的路径为什么存在,为什么没有
通过功能上合理的路径得到覆盖。
三、路径覆盖举例
[例2]试用路径覆盖测试法为采用冒泡排序
(bubblesorting)法进行数据排序的C程序
设计测试用例。
设计方法:
(1)将图2表示的程序流程图转换为图
7表示的控制流图。
C程序的控制流图
(2)按照路径选取的原则选择足够多的路径,使之覆盖所有结点和边,设计的测试用
例如下:
测试用例
覆盖的结点
①②③④⑤⑥⑦⑧⑨
覆盖的边
abcdefghljklmnq
a={6,10},k=2
|VVVV
VVVVV
a={6,6},k=2
VVVVV
VVVVVV
|a={6,10,10},k=3
VVVVV
VVVVVVV
[a={10,6},k=2
VVVVVVVVV
VVVVVVVVVVV
a={10,6,6},k=3
VVVVVVVVV
VVVVVVVVVVVV
a={10,6,8},k=3
VVVVVVVVV
VVVVVVVVVVVV
以上6个测试路径达到覆盖的最低标准.
(3)对循环选取如下测试用例
循环测试内容
测试用例
外循环零次
a={6},k=1
外循环最大次,内循环零次
a={1,2,…,10},k=10
外循环最大次,内循环最大次
「a={10,9,…,1},k=10
5.3黑盒测试的测试用例设计
5.3.1等价类划分
等价类划分是一种典型的黑盒测试方法。
其基本思想是将程序的输入区域划分为若干
个等价类,用每个等价类中的一个具有代表性的输入数据作为测试数据。
对于上述基本思想,我们也可以这样来理解:
如果某个等价类中的一个输入数据作为测试用例查出了错误,那么使用这一等价类中的其它输入数据进行测试也会查出同样的错误;反之,若使用某个等价类中的一个输入数据作为测试用例未查出错误,则使用这一等价
类中的其它输入数据进行测试也同样查不出错误。
这样就可以用少量有代表性的测试用例来
代替大量内容相似的测试用例,以提高测试的效率,并取得良好的测试效果。
在划分等价类时,我们可以将之划分为两类:
(1)有效等价类:
是指对程序的规格说明是合理的、有意义的输入数据所构成的集合。
有效等价类可以是一个,也可以是多个。
利用它可以检验程序是否实现了程序的规格说明预先规定的功能和性能。
(2)无效等价类:
是指对程序的规格说明是不合理的或无意义的输入数据所构成的集合。
无效等价类至少有一个。
利用它可以检验程序中的功能和性能是否不符合程序的规格说明。
确定等价类有以下几条原则:
(1)如果一个输入条件规定了输入值的范围,则可确定一个有效等价类和两个无效等价类。
例如,在程序的规格说明中,对某一个输入条件规定:
X值的范围是1~999,则可以
确定有效等价类为“KXW999”,无效等价类为“X<1”及“X>999”。
(2)如果一个输入条件规定了值的个数,则可确定一个有效等价类和两个无效等价类。
例如,在程序的规格说明中,规定每个班学生人数不超过40人,则可以确定有效等价
类为“1W学生人数W40”,无效等价类为“学生人数=0”及“学生人数>40”。
(3)如果一个输入条件规定了值的集合,而且有理由确信程序对每个输入数据都分别
进行处理,则可以确定一个有效等价类(在集合中的所有元素)及一个无效等价类(不在集
合中的元素)。
(4)如果一个输入条件规定了“必须如何”的条件,则可以确定一个有效等价类及一个无效等价类。
例如,输入条件规定“标识符应以字母开头…”,则可以确定“以字母开头者”为有效
等价类,“以非字母开头者”为无效等价类。
(5)如果有理由确信某一个已划分的等价类中各元素在程序中处理方式不同,则应将
此等价类划分成更小的等价类。
等价类划分好后,可按下面的形式列出等价类表:
输入条件
有效等价类
无效等价类
选择测试用例的基本步骤是:
(1)给每个等价类规定一个唯一的编号;
(2)设计新的测试用例,使它覆盖尽可能多的尚未被覆盖的有效等价类,重复这一步,
直到所有有效等价类均被覆盖为止;
(3)设计新的测试用例,使它覆盖一个且仅一个未被覆盖的无效等价类,重复这一步,直到所有无效等价类均被覆盖为止。
必须注意,对有效等价类,一个测试用例可以覆盖几个,因此应该用尽可能少的测试
用例去覆盖所有有效等价类;对无效等价类,一个测试用例只能覆盖一个,这是因为程序中
的某些错误检测往往会抑制其它的错误检测。
[例3]某省高考招生,规定考生的年龄在16周岁至25周岁之间,即出生年月从1978
年7月至1987年6月。
高考报名程序具有自动检测输入程序的功能。
若年龄不在此范围内,
则显示拒绝报名的信息。
试用等价类划分法为该程序设计测试用例。
设计方法:
(1)划分有效等价类和无效等价类。
假定年龄用6位整数表示,前4位表示年份,后2位表示月份。
输入数据有出生年月、数值本身、月份3个等价类,并为此划分有效等价类和无效等价类,见下表:
输入条件
有效等价类
无效等价类
②有非数字字符
出生年月口
|①6位数字字符H
③少于6位数字字符
④多于6位数字字符
6<197807
7>198706
数值本身
⑤在197807~198706之间
9等于00
10>12
月份口
⑧在01~12之间
(2)设计有效等价类需要的测试用例。
为覆盖①、⑤、⑧三个有效等价类,可以设计
一个共用的测试用例:
测试数据
预期结果
r测试范围
198011
输入有效
①、⑤、⑧
(3)为每一个无效等价类至少设计一个测试用例:
测试数据
预期结果
|测试范围
May,79
输入无效
②
19803
输入无效
|③
1981112
输入无效
「④
197602
年龄不合格
⑥
199003
年龄不合格
⑦
197900
输入无效
⑨
198013
输入无效
⑩
等价类划分法显然比随机地选择测试用例要优越得多,但它的不足是忽略了某些效率较高的测试情况。
5.3.2边界值分析
边界值分析是对等价类划分法的补充。
所谓边界值分析,就是选择这样的测试用例,它能使被测程序在边界值及其附近运行,从而更有效地暴露程序中隐藏的错误。
因为经验告诉我们,程序常常在处理边界情况时易于犯错误,所以检查边界情况的测试用例往往是高效的。
所以输入等价类和输出等价类就是我
们应着重测试的边界情况。
应当选取正好等于、刚刚大于或刚刚小于边界的值作为测试数
边界值分析法与等价类划分法有两个方面的区别:
(1)边界值分析法不是从某个等价类中随便设计一个数据作为测试用例,而是选出
一个或多个数据,使得这个等价类的每个边界值都要作为测试数据;
(2)边界值分析法不仅要考虑程序的输入空间,而且要根据输出空间设计测试用例
用边界值分析法设计测试用例时,有以下几条原则:
(1)如果输入条件规定了值的范围,则取刚达到这个范围的边界的值,以及刚刚超
出范围的无效数据作为测试用例。
例如输入值的范围为-100~+100,则可以选取-100、+100、-101、+101作为测试数据。
(2)如果输入条件规定了值的个数,则用最大个数、最小个数、比最大个数多1、比最小个数少1的数作为测试用例。
例如有规定“某文件可包括1至255个记录…”,则测试数据可选1和255及0和256等值。
(3)对每个输出条件使用第
(1)条原则。
例如有个程序计算每月的保险金额,若最小额是0元,最大额是1000元,那么就应
设计导致扣除0元和1000元的测试数据。
另外还应考虑是否可设计使程序扣除负额或大于1000元的测试数据。
(4)对每个输出条件使用第
(2)条原则。
例如一个情报检索系统根据某一输入请求,显示有关文献的摘要,但不能多于4条摘
要,那么就可以设计一些测试用例,使得程序分别显示1篇、4篇或0篇摘要,并设计一个
有可能使程序错误地显示5篇摘要的测试用例。
(5)如果程序的输入域或输出域是个有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例。
(6)如果程序中使用了一个内部数据结构,则应当选择这个内部数据结构的边界上的值作为测试用例。
例如,如果程序中定义了一个数组,其元素下标的下界是0,上界是100,那么应选
择达到这个下标边界的值,如0与100作为测试用例。
(7)分析规格说明,找出其它可能的边界条件。
[例4]程序同例3。
试用边界值分析法为该程序设计测试用例。
设计方法:
利用等价类划分法设计了3个输入等价类:
出生年月、数值本身、月份。
采用边界值分析法可为这3个输入等价类设计14个边界值测试用例。
见下表:
输入等价类
测试用例说明
测试数据
期望结果
选取理由
1个数字字符
5
仅有1个合法字符
「出
5个数字字符
「19791n
比有效长度恰少1个字符〕
生
7个数字字符
1980121
输入无效
比有效长度恰多1个字符〕
年
有1个非数字字符
1981m
非法字符最少丁
]月
全是非数字字符
AUGUST
非法字付最多
6个数字字符
198108
输入有效
有效的输入—|
\\数
16岁
198706
合格年龄
最小合格年龄[
值
35岁
197807]
最大合格年龄
本
<16岁
198707
不合格年龄
恰小于合格年龄n
L身
>35岁
197806
恰大于合格年龄]
月份为01
197901
最小月份
月
输入有效
月份为12
198112
最大月份]
份
月份<01
197900
输入无效
恰小于最小月份
月份>12
198113
人人f-nr曰{,口/八
恰大于最大月份
5.3.3错误推测法
错误推测法就是根据经验或直觉来推测程序容易发生的各种错误,然后有针对性地设