一种基于RRT技术的面向对象软件测试方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一种基于RRT技术的面向对象软件测试方

近年来,越来越多的软件开始采用面向对象(object oriented,OO)的开发技术, OO具有封装、继承、多态3大特性, 这些特性使得面向对象编程(object oriented programming,OOP)具有很多其他编程语言无法企及的优点,例如面向对象技术可以提高软件的可复用性,使得软件开发速度更快且更易于维护.但同时面向对象语言这些独有的特性也给软件测试带来了一定的影响.当前,所有测试面向对象程序的方法中最常使用的是随机测试(random testing,RT).RT从整个输入域中随机挑选测试用例并执行,即所有程序输入被选为测试用例的概率都相同,以便不会跳过任何程序错误.试验证明,虽然RT挑选测试用例的时间花费较低,但是发现程序错误所使用的测试用例数量比较大.基于上述问题,CHEN T. Y.等提出了改进后的RT方法即自适应随机测试(adaptive random testing,ART)方法.
与RT方法相比,ART方法在测试面向对象软件时使用的测试用例更少,发现的错误更多,且使用ART挑选的测试用例可以均匀地分布在整个输入域中;现如今有基于不同概念的ART算法被提出,并且这些算法被用到不同的领域之中.基于限制性区域的自适应性随机测试(restricted random testing,RRT)算法是一种常用的ART实现方案.RRT在所有已执行测试用例周围的输入域空间生成1个排斥区域,然后一直重复随机生成测试用例,直到随机生成的测试用例在所有排斥区域之外,则将其选为下一个测试用例.试验证明,RRT算法的有效性优于RT算法,能够减少测试用例的个数].
文中将RRT方法应用到面向对象软件测试中,讨论基于RRT的面向对象测试用例的距离度量公式,并提出一种基于RRT的面向对象的测试用例生成算法,同时1个基于RRT的面向对象软件测试原型系统也被设计和实现.
1 RRT算法
RRT算法是一种基于排斥区域的ART算法,其算法思想如下:首先从整个输入域中随机挑选1个测试用例,当有n(n≥1)个已执行测试用例时,RRT会围绕每个已执行测试用例定义1个排斥区域.所有的排除区域的值为R·d/n,其中d为输入域的大小;R为目标排除比率,由测试人员设置.然后在输入域中继续随机生成候选测试用例,直到这个候选测试用例在排斥区域之外,才将其作为下一个测试用例.以图1为例说明输入域为一维的情况,输入域为(0,1);设置R的值为0.75,t1是随机生成的,第2个测试用例只能从排斥区域(t1-0.375*d/1,t1+0.375*d/1)之外选取(图1a),同样地,第3个测试用例也只能在排斥区域(t2-0.375*d/2,t2+0.375*d/2),(t1-0.375*d/2,t1+0.375*d/2)外选取(图1b).
图1 一维情况下的RRT算法实例
RRT算法的具体步骤如下:
double oneTest=rand.NextDouble() /*随机生成oneTest并执行*/
while(没有达到程序终止条件)
add oneTest to excuteds
bool flag=true /*flag是1个标志位,用来表示测试用例是否在排除区域之外*/
while (flag){
flag=false;
oneTest=rand.NextDouble()/*随机生成1个候选测试用例oneTest*/ for (int i=0; i<excuteds.Count; i++)
/*判断测试用例是否在排除区域之外*/
if(oneTest不在排除区域)
flag=true;
break;
end if
end for
end while
end while
模拟和实证研究表明,RRT在检测软件故障方面比RT更有效,其故障检测有效性变得更高.
2 OOS测试用例度量方法
2.1 距离表现形式
参考文献[19]的方法,采用a+b i的形式来表示测试用例之间的距离,其中i表示1个虚数单位,a,b分别表示主距离和辅助距离.
2.2 距离的运算
假设2个距离分别为p=a+b i和q=m+n i,其中a,m表示主距离,b,n表示辅助距离.则p,q的四则运算就是相应主距离和副距离的四则运算.
判断2个距离间的关系时需要对主距离和辅助距离进行分别判断,对于2个距离p,q,只有当a=m且b=n时才有p=q;当a>m时或者a=m且b>n时才使得p>q;同样当a<m时或者a=m且b<n时才有p<q.
2.3 测试用例距离度量
将RRT算法应用到面向对象中,最重要的就是定义测试用例之间的距离计算公式.本节在大量文献基础上,综合分析了各种参考资料[20-22],给出了试验中所使用的测试用例间距离的度量公式.
在测试面向对象的程序时,测试用例即为对象,则测试用例由属性和方法组成,其中属性为静态部分,方法为动态部分,其结构图如图2所示.
由图2可知,测试用例的距离由静态部分和动态部分组成.静态部分包括自定义属性、继承属性以及嵌套属性.为了方便直接将继承属性合并到自定义属性.动态部分包括自定义方法和继承方法.为了方便计算也将继承方法直接合并到自定
义方法中.可以用p,q来表示2个测试用例,利用p.s和q.s表示测试用例的自定义属性,利用p.s.d和q.s.d表示2个测试用例的元素,利用p.s.d.type和q.s.d.
type表示测试用例的类型;利用p.s.e和q.s.e表示2个测试用的嵌套属性;利用p.b和q.b表示2个测试用例的动态部分.
图2 测试用例结构图
所以2个测试用例之间的距离可以表示为静态距离加动态距离:
ObjectDistance(p,q)=StaticDistance(p.s,q.s)+
BehaviorDistance(p.b,q.b),
(1)
其中静态距离可以表示为自定义属性距离加嵌套属性距离:
StaticDistance(p.s,q.s)=defineDistance(p.s,q.s)+
embedDistance(p.s,q.s),
(2)
其中自定义属性距离可表示为元素距离加类型距离:
DefineDistance(p.s,q.s)=
elementaryDistance(p.s.d,q.s.d)+
typeDistance(p.s.d.type,q.s.d.type).
(3) 其中元素距离可以表示为
elementaryDistance(p.s.d,q.s.d)=
(4) 式中distance函数是计算2个属性数值差的绝对值并除以该属性的范围. 类型距离可以表示为
typeDistance=
|size(p.s.d.type)-size(q.s.d.type)|+
|size(p.s.d.type)∪size(q.s.d.type)|-
|size(p.s.d.type)∩size(q.s.d.type)|.
(5) 静态距离中还有一部分是嵌套属性距离,嵌套属性距离由对象集合距离组成:
embedDistance(p.s.e,q.s.e)=
objectSetDistance(p.s.e,q.s.e)*a,
(6) 式中a为衰变系数.
对象集合的距离公式如下:
(7)
式中:OBJ[i]为第i个对象;m为2个对象集合数量的最大值,即m=max{size(p.OBJ),size(q.OBJ)};Arr为[1,2,3…m]的所有全排列的集合,共有m!种情况,Arr[i]表示所有全排列情况中的第i种情况,Arr[i][j]表示第i种全排列情况下,第j个元素的值.
动态距离计算公式为
behaviorDistance(p,q)=|size(p.b.m)-size(q.b.m)|+
1-size(p.b.m∩q.b.m)/[size(p.b.m∪q.b.m].
(8)
首先计算2个对象的自定义属性集合中成员变量数量上的差异,在这里取绝对值,然后计算2个对象的自定义属性集合中成员变量的并集与成员变量交集之差,在这里也取绝对值,最后将这两部分加起来就得到了这2个对象的类型距离.
3 RRT中面向对象测试用例生成
3.1 RRT算法测试流程
基于RRT算法的面向对象测试先根据输入的类图的信息利用类的构造函数创建对象,然后为对象的各个参数赋值,使用RRT算法挑选测试用例并执行之后对测试结果进行记录和分析.测试流程图如图3所示.
图3 测试流程图
基于RRT算法的面向对象测试的具体测试流程如下:
1) 获取类图信息并保存.
文中试验均使用基于RRT算法的原型系统完成,此原型系统中包括类图输入模块,进行程序测试之前首先在类图输入模块设置所需信息(主要包括当前类是否为基类或其所继承的类的信息,以及当前类的基本成员信息),然后将填写完整的类图信息保存到文件,每次试验只需读取文件中的信息即可.
2) 随机生成第1个测试用例.
主要是根据输入类的信息来随机生成第1个测试用例,根据类图信息文件创建对象,创建对象时不仅需要当前类名,还需要随机产生对象的参数,参数类型为各个基本数据类型,系统中的随机数生成算法负责对象参数的生成,算法根据对象调用时传入的参数类型和取值范围来随机生成成员变量的值.
3) 执行第1个测试用例.
将第1个随机生成的测试用例用于测试面向对象程序,如果达到程序结束条件则退出并记录最终结果;若没有满足结束条件则在记录试验结果后继续执行下一步.
4) 使用RRT算法挑选下一个测试用例.
使用RRT挑选可使用的测试用例时,第1个测试用例为随机生成,执行完该测试用例之后若没有达到程序结束条件,则在该测试用例周围生成可选区域和排除区域;挑选下一个测试用例时,RRT每次都先调用测试用例生成算法随机生成1个测试用例,然后判断其是否在排斥区域内,若在则丢弃,反之则选为下一个测试用例并执行;在满足程序结束条件之前将反复执行上述步骤.
5) 执行下一个测试用例.
将RRT算法挑选出的测试用例用于测试函数,并分别记录每一次的试验结果,同测试数值型试验一样,这里的试验依然使用F-measure(发现第1个程序错误时所使用测试用例的数量)和E-measure(预期导致程序出错测试用例的总数)2种评价方法对算法进行评估.
6) 收集结果.
主要任务就是收集每一次的试验结果,即RRT算法的执行结果.为了验证算法的准确性文中进行了大量的试验,本步骤把所有试验收集结果之后还需要对其进行统计,最后把统计后数据保存.
7) 分析结果.
对上一步骤中保存的试验结果数据进行分析,主要是对比分析RRT和RT算法的各项试验数据,即F-measure,Fm-time和E-measure,Em-time的试验结果;然后根据试验数据比较2种算法的有效性,最后将分析结果以图表或文件的形式保存.
3.2 RRT算法在面向对象中的应用
面向对象的试验中,文中实现了RRT在测试同1个类中的应用.在测试面向对象程序时,测试用例的生成需要依赖当前待测类的类图信息.所以在使用RRT 算法测试面向对象型程序时,需要先输入待测类的具体信息.在试验所用到的原型系统中有1个类图信息录入模块,在该模块中完成类的创建,然后根据类图信息使用类的构造函数创建对象,并调用随机数生成算法为对象中的各个成员赋值.随机数生成算法用来随机生成对象所需的参数,主要包括基本数据类型的随机数生成,根据所传参数的数据类型来调用相应的随机数生成器,然后在指定的范围内随机生成参数的值并返回.试验中用到的基本数据类型有int,float,double,bool,string以及char类型,其中int,float,double类型的取值范围为(0,100);string类型长度的取值范围为(0,10);char类型的取值范围是Unicode最大值与最小值之差.
除了测试用例的生成之外,在测试面向对象程序时还需要考虑测试用例之间的距离计算,根据公式(1)-(8)来度量测试用例之间的距离;文中面向对象的试验完成了同一个类的测试,所以在测试待测类时,测试用例的方法和属性类型均相同,只有引用对象和基本数据类型的值不同,即在计算任意2个测试用例间的距离时,只需要考虑辅助距离的差异.上文中给出了各基本数据类型的取值范围,试验中所
用到的输入域A的起始点为0,终点即为各取值范围的最大值相加;排除区域为(A ×R)/n,则排除半径为(A×R)/(2×n),其中n为已执行测试用例的个数;R为排除比率,试验中R取值为0.75.
RRT算法在测试面向对象程序时的基本思想同数值型的试验基本相同,第1个测试用例t1在输入域中随机生成,执行测试用例t1后若没有满足程序结束条件则会在t i周围生成1个排除区域(t i-(R×A)/(2×n),t i+(R×A)/(2×n));继续在输入域中随机生成下一个测试用例,然后调用测试用例距离度量算法TDC(testcase distance calculate)计算2个测试用例间的距离,并判断此距离的大小,若距离大于排除区域半径则将其挑选为下一个测试用例,反之则丢弃;接着执行该选中的测试用例,同样地如果没有达到程序终止条件则继续按照之前的步骤挑选下一个测试用例.
TDC算法的具体步骤如下:
设置TestCase1,TestCase2,dist/* dist表示2个测试用例间的距离*/
if(TestCase1==TestCase2)
dist=0;
end if
else
dist=static distance(TestCase1,TestCase2)+behavior distance(TestCase1,TestCase2)
end else
/*下面计算static distance,static
distance=elementary distance+embed distance*/
if(2个测试用例的静态部分都为空)
static distance=0
end if
else if(有1个静态部分为空)
static distance=1
end if
else
static distance=elementary distance+embed distance end else
float allTypeDist,oneTypeDist
foreach(每一种类型)
for(int i=0;i<TestCount.count;i++)
/*为计算元素类型距离的方法,下文会给出*/ oneTypeDist+=distance
(TestCase1[i].value,TestCase2[i].value,type)
end for
allTypeDist+=oneTypeDist
end foreach
为实现TDC算法,则需要计算distance,具体实现算法如下:
/*下面描述distance方法*/
switch(type)
case “int”:∥float,double,char,string省略
f1=float.Parse(value1.value);
f2=float.Parse(value2.value);
range=Math.Max(value1.typeRange.max, value2.typeRange.max)-Math.Min(value1.typeRange.min, va-lue2.typeRange.min);
return (float)(Math.Abs(f1-f2)/range);
case “bool”:
if(values1.value==values2.value)
return 0;
end if
else
return 1;
end else
end switch
/*下面计算embedded distance*/
embedded distance=objectSet distance/2;
/*下面计算objectSet distance*/
if((object1==null)&&(object2==null))/*2个引用均为空*/
objectSet distance=0
end if
if((object1==null)||(object2==null))/*有1个引用为空*/
objectSet distance=2;
end if
else if(互相引用)
objectSet distance=2*dist
end if
else
objectSet distance=objectSet
distance(object1,object2)/*递归计算*/
end else
综上,TDC算法就是前面所说的距离度量公式的实现,其中静态包括自定义属性距离的计算和嵌套属性距离的计算.自定义属性计算部分又包括元素距离和类型距离:元素距离与测试用例的属性个数有关,而类型距离与属性类型有关.嵌套属性的距离计算和嵌套的层数有关.
4 试验系统设计
4.1 试验系统测试流程
测试面向对象软件时的主要流程如下: ①首先在类图信息录入模块输入待测类的详细信息; ②将待测类的相关信息保存配置到XML文件中,以便每次试验时读取该类的配置参数; ③生成测试用例并执行;根据待测类的配置参数创建对象实例,然后为对象的基本类型成员赋值; ④记录测试用例执行的试验结果;
⑤分别使用RRT和RT算法挑选测试用例; ⑥分别将2种算法挑选出的测试用例用于测试程序; ⑦记录试验结果,获得2种算法的F-measure,Fm-time值以及E-measure,Em-time值; ⑧对比分析试验结果并总结.
4.2 系统模块分析
在测试面向对象软件中,执行算法之前需要输入详细的类图信息,在类图信息录入模块进行各个所需信息的录入,并把录入的类图信息保存到文件中以便试验时读取.同数值型测试一样,该模块也为每个算法设计了独立的页面,执行算法时只需进入相应的页面将所需的参数配置文件载入,然后即可开始执行算法,最后将结果文件保存到相应的路径,图4给出了RRT系统快照.非数值型模块主要包括类图信息录入、算法执行、测试用例距离计算和结果统计分析模块,下文具体介绍这些模块.
图4 RRT系统快照
4.2.1 类图信息录入模块
点击系统中的类图信息录入选项即可进入类图信息录入界面,该界面主要包括类的信息、方法信息和对象信息录入3个部分,点击不同的选项卡即可进行不同信息的录入.
在进行类信息录入时主要包括类名和基本类型成员信息,在录入基本成员信息时,除了成员名称之外还需要选择成员类型,并且需要为每种基本成员设定最大值和最小值,设定最大值和最小值的目的是为了计算每个类型的取值范围,用于计算测试用例之间的距离;最后还要选择每个基本成员的权限值.在所有的选项都填写完毕后,点击添加成员按钮即添加成功,可以在类信息录入界面中的成员列表中看到已经添加的类的成员.当所有类信息输入完毕后点击添加类按钮即可完成当前类的创建,同时在该界面的已有类选项中可以看到当前系统中所有已存在的类.在所有类信息录入完毕后系统会将类图信息转化成二进制文件以便试验中使用.
为自定义类中添加自定义方法时就需要进行方法的录入,在方法录入时首先选择它所属的类,这里的类时是当前系统中已存在的类,录入方法时必须选择所属类.然后录入方法的名称、返回值以及权限值等信息;方法信息录入完毕后点击添加方法按钮即可完成自定义方法的创建,然后在方法列表项里即可看到新创建的方法.
对象信息录入就是进行自定义类的实例化操作,首先录入对象的名称,然后选择该对象的所属类,同自定义方法一样,对象的所属类也必须是已经存在的类.在为对象中的成员变量赋值时,需要先判断成员变量的类型,如果是基本数据类型则在相应的范围内随机生成变量的值;若是引用类型则需先选择其所引用的对象的
名称,然后再进行赋值操作;在所有成员变量赋值完毕之后点击添加对象按钮完成对象的创建.
4.2.2 算法执行模块
该模块同数值型程序测试中的算法执行模块相似,同样为RRT算法设计了独立的操作界面,点击相应的选项卡即可进入算法执行界面.在执行算法之前需要完成2个路径的填写,分别是测试用例生成的参数配置文件和测试结果文件的保存路径.其中配置文件中不仅含有失效率、种子值等信息,最重要的是类信息,即在系统中录入的待测类信息,所由参数配置完毕后保存为xml文件的形式,在执行算法之前将该xml文件路径填写到相应位置即可.除了配置文件的路径之外,同样的非数值型程序中的算法执行模块也需要1个结果文件的保存路径.在这2个路径配置完毕之后点击开始测试按钮即可开始执行相应的算法.
4.2.3 测试用例距离计算模块
该模块的主要任务是进行测试用例之间的距离计算,在计算测试用例的距离之前需要先进行测试用例的添加,然后选择2个待计算的测试用例进行计算.在计算时首先获取每个测试用例中存储的成员变量信息,然后根据计算公式(1)-(8)进行测试用例间的距离度量.
4.2.4 结果分析模块
该模块同数值型测试的结果统计模块一样,也是将结果保存为txt文件,然后将该txt文件分别以匹配信息为关键字转换成excel文件,最后在excel文件中统计每种试验结果.
5 试验结果分析
算法的有效性度量主要包括P-measure[23],F-measure[19]和E-measure[24],其中P-measure是指至少发现1个错误的概率,E-measure是指预期发现的错误的总数,F-measure是指发现第1个错误所需要的测试用例数量.因此,1个测试方法和其他测试方法相比,如果拥有更高的P-measure、更高的E-mea-sure和更低的F-measure,则表示该方法检测错误的效率更高.试验中采用的是F-measure和E-measure这2种评价方法.
5.1 F-measure试验结果对比
模拟类测试的F-measure试验结果如表1所示,试验中对2个模拟类分别进行了测试,其中模拟类1和模拟类2分别包含了3个和5个公共方法;2个模拟类均包含了int,double,bool,char,float这5种基本数据类型;其中为模拟类1植入了3个错误,为模拟类2植入了4个错误.
表1模拟类1和2的F-measure试验结果
由表1可见,和RT相比,RRT算法在发现第1个程序错误时使用的测试用例个数少.
在测试开源类库时,选取的C#类库为Stack 和Queue,并将这2个类库改为只包含1个类,其中Stack类库包含5个方法,Queue类库包含4个方法;并为
Stack和Queue分别植入3个和2个错误.这2个类的F-measure试验结果如表2所示.
表2Stack和Queue的F-measure试验结果
由表2可见,在测试开源类库时和模拟类的结果基本一致,即RRT算法的F-measure值和Fm-time值都更低,说明RRT在发现第1个程序错误时使用的测试用例个数少;这表明在面向对象的试验中,RRT算法能够很好地改善RT测试用例用例过多的弊端.
5.2 E-measure和Em-time试验结果分析
E-measure值也是评判面向对象算法有效性的重要指标之一.2个模拟类的E-measure试验结果如表3所示,Em-time如图5所示.
表3模拟类1和2的E-measure试验结果
图5 模拟类1和模拟类2的Em-time试验结果
文中对2个模拟类和2个开源类库分别做了用例个数为100,500,1 000,1 500,2 000的试验,E-measure试验中测试的2个模拟类库同F-measure试验中测试的是完全相同的.并且根据种子值的差异每种类的试验都进行了100次,最后的结果为这100次试验结果的平均值.这2个类的E-measure的试验结果如表3所示.
为了试验的完整性,对2个开源类库分别进行用例为100, 500, 1 000, 1 500, 2 000的试验,与模拟类的测试相同,分别进行了100次试验,最后结果是100次试验平均值.同时和F-measure试验一样,在E-measure试验中依然为Stack和Queue分别值入3个和2个错误.试验结果如表4所示.
表4Stack和Queue的E-measure试验结果
从模拟类和开源类的E-measure试验中可以看出,RRT和RT算法在测试面向对象程序时的E-measure值相差不大,即2种算法在使用相同用例个数的情
况下发现的程序错误总数基本相同,即它们发现错误的能力是相同的,但是相比RT,RRT使用的测试用例更少,效果更好.
6 结论
1) 实现了RRT算法在面向对象中的应用.首先提出了测试用例间的距离表现形式,在对测试用例的结构分析之后,将测试用例间的距离定义为静态部分和动态部分距离之和,并分别给出了各部分的距离计算公式,最后计算出测试用例间的距离,实现了RRT在面向对象中的应用.
2) 设计并实现了1个测试工具原型系统.系统中实现了试验中所使用的距离计算公式,然后指出了面向对象程序的测试流程,并给出了类图信息的存储结构以及面向对象测试用例生成方法,系统中的测试模块主要有类图信息录入模块、测试用例距离度量模块、算法执行模块等.在该系统上做了大量试验,验证了提出方法的有效性.。

相关文档
最新文档