白盒设计方法分为静态和动态。

1 静态

静态的白盒测试方法有桌面检查、代码审查、代码走查和代码扫描工具。

2 动态

动态的白盒测试方法有逻辑覆盖法和基本路径测试法。

2.1 逻辑覆盖

逻辑覆盖法有语句覆盖、判定覆盖、条件覆盖、判定条件覆盖、条件组合覆盖和路径覆盖。

例1

int a=0;
public class E01(int x,int y,int m){
	if(x>&&y>0){
	 	a=x+y;//语句块1
	}
	else{
		a=x-y;//语句块2
	}
	if(m<0){
		a=m;//语句块3
	}
	return a;//语句块4
}

将上述程序画出流程图,如下:

在这里插入图片描述

2.1.1 语句覆盖

语句覆盖,就是设计若干个测试用例,运行被测程序,使得每一可执行语句至少执行一次。度量被测代码中每个可执行语句是否被执行到了。
语句覆盖标准最弱,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。
语句覆盖率=可执行的语句总数/被评价到的语句数量 x 100%

将例1进行语句覆盖,写出测试用例如下:

数据语句
x=1,y=1,m=21,4
x=-1,y=-1,m=-22,3,4

若将语句块1改为if(x>0||y>0),语句覆盖还是覆盖成功,不符合测试需求。因为语句覆盖不能准确的判断运算中的逻辑关系错误。(语句覆盖的缺点)

2.1.2 判定覆盖

定义:判定覆盖使设计的测试用例保证程序中每个判断的每个取值分支(ture or false)至少经历一次。
【优点】:判定覆盖具有比语句覆盖更强的测试能力。同样分支(判定)覆盖也具有和语句覆盖一样的简单性,无须细分每个判定就可以得到测试用例。
【缺点】:往往大部分的分支(判定)语句是由多个逻辑条件组合而成,若仅仅判断其整个最终结果,而忽略每个条件的取值情况,必然会遗漏部分测试路径。判定覆盖仍是弱的逻辑覆盖。

将例1进行判定覆盖,写出测试用例如下:
P1为“x>0&&y>0”判定,P2为“m<0”判定

P1P2用例
TFx=1,y=1,m=1
FTx=-1,y=-1,m=1
FFx=-1,y=-1,m=-1
TTx=1,y=1,m=-1

只要满足了判定覆盖标准就一定满足语句覆盖标准。
判定覆盖会忽略条件中取或(or)的情况。
若将语句块1改为if(x>0||y>0),判定覆盖还是覆盖成功,不符合测试需求。

2.1.3 条件覆盖

定义:设计足够多的测试用例,运行被测程序,使得每一判定语句中每个逻辑条件的可能取值至少满足一次。
回头看例1的流程图,判定条件定义如下:
x>0&&y>0判定记为:P1
m<0判定记为:P2
x>0记为:C1
y>0记为:C2
m<0记为:C3

测试用例设计如下:

C1C2C3P1P2用例路径
TFTFTx=1,y=-1,m=-1acd
FTFFFx=-1,y=1,m=-1ace

条件覆盖比判定覆盖,增加了对判定中所有条件的测试。
但条件覆盖并不能保证判定覆盖。例如:P1为真,没有覆盖。

2.1.4 判定条件覆盖

定义:设计测试用例,使得被测试程序中的每个判断本身的判定结果(真假)至少满足一次,同时,每个逻辑条件的可能值(真假)也至少被满足一次。即同时满足100%判定覆盖和100%条件覆盖的标准。

判定条件覆盖率=每个判断本身的判定结果(真假)至少满足一次/判定结果的总数+条件结果的总数

例1代码中有2个判定,条件3个。所以,判定结果为2* 2(true,false)=4个,条件结果3*2(true,false)=6个。
设计测试用例执行3个判定结果,5个条件结果,判定条件覆盖率为:(3+5)/(4+6)=80%

将例1进行判定条件覆盖,写出测试用例如下:

C1C2C3P1P2用例路径
TTFTFx=1,y=1,m=1abe
FFTFTx=-1,y=-1,m=-1acd

满足判定条件覆盖标准,一定能够满足条件覆盖、判定覆盖和语句覆盖。
判定条件覆盖会忽略条件中取或(or)的情况。

2.1.5 条件组合覆盖

定义
判定中条件的各种组合都至少被执行一次。
特点
(1)满足条件组合覆盖的用例一定满足语句覆盖、条件覆盖、判定覆盖和判定覆盖。
(2)条件组合覆盖没有考虑各判定结果(真或假)组合情况,不满足路径覆盖
(3)条件组合数量大,设计测试用例的时间花费较多。

例1使用条件组合覆盖,测试用例设计如下:

C1C2C3P1P2用例路径
TTTTTx=1,y=1,m=-1abd
TFTFTx=1,y=-1,m=-1acd
FTTFTx=-1,y=1,m=-1acd
FFTFTx=-1,y=-1,m=-1acd
TTFTFx=1,y=1,m=1abe
TFFFFx=1, y=-1,m=1ace
FTFFFx=-1,y=1,m=1ace
FFFFFx=-1,y=-1,m=1ace
2.1.6 路径覆盖

定义
使程序的每条可能路径都至少执行一次。
特点
路径覆盖可以对程序进行彻底的测试,比前面五种覆盖面都广。

C1C2C3P1P2用例路径
TTTTTx=1,y=1,m=-1abd
TTFTFx=1,y=1,m=1abe
TFTFTx=1,y=-1,m=-1acd
FFFFFx=-1,y=-1,m=1ace

2.2 基本路径测试法(重点)

定义
在程序控制流图的基础上,通过分析程序的环路复杂性,导出基本可执行路径集合,从而设计测试用例。
步骤
第一步,根据代码画出程序控制流图;
第二步,计算程序的环路复杂度;
第三步,导出可执行路径;
第四步,设计测试用例。

void Sort(int a,int b){
	int x=0;
	int y=0;
	while(a-- >0){ //将此判断记为P1
		if(0==b) //将此判断记为P2
			x=y+2;break; //将此语句记为s1
		else
			if(1==b) //将此判断记为P3
				x=y+10; //将此语句记为s2
			else
				x=y+20; //将此语句记为s3
	}
}

第一步,控制流图,如下图:
在这里插入图片描述
第二步,计算程序环路复杂度
方法有三种:
流图中区域的数量对应于环型的复杂性。

在这里插入图片描述

给定流图G的圈复杂度V(G),定义为V(G)=E-N+2,E是流图中边的数量,N是流图中节点的数量。技巧:边数——数箭头,结点——数判断框和语句
边数10,结点8,所以V(G)=10-8+2。

给定流图G的圈复杂度V(G),定义为V(G)=P+1,P是上图中判定节点的数量。V(G)=3+1

用环路复杂度验证测试用例是否覆盖全了。

第三步,导出可执行路径
回头看例子的程序流程图,此例子可导出路径为:
路径1:P1-退出程序
路径2:P1-P2-S1-退出程序
路径3:P1-P2-P3-S2-退出P3-P1-退出程序
路径4:P1-P2-P3-S3-退出P3-P1-退出程序

第四步,设计测试用例

测试数据覆盖路径
a=0路径1
a=1,b=0路径2
a=1,b=1路径3
a=1,b=2路径4

小结

白盒测试主要应用于单元测试阶段。白盒设计用例一般使用基本路径测试,重点模块使用多个覆盖率标准。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐