一个基于UML协作图的集成测试用例生成方法(三) 文章出处: 作者:王林章

来源:互联网 发布:叁度装修预算软件 编辑:程序博客网 时间:2024/05/17 05:18
 
一个基于UML协作图的集成测试用例生成方法(三)
 
文章出处: 作者:王林章 发布时间:2005-10-26
 

3、基于协作图生成集成测试用例的方法
3.1研究假定
为了有针对性地解决从协作图生成测试用例的问题,本文作出如下假定和要求:
(1)假定协作图描述的协作与用例图描述的规约是一致的。模型本身的验证是通过非形式化的复审和形式化的模型检验方法进行的,已超出本文的研究范围;如果协作图上的场景路径集不能覆盖所有消息,则说明协作图本身有错误;
(2)假定系统中的对象都是自行开发的,不包括第三方组件对象,文中的对象可以是不同粒度的对象(类的实例、类簇、组件、子系统、系统),也就是说我们在分析任意对象或类时,在必要的情况下都可以获取其规约和内部详细设计信息,包括功能和结构信息;对于第三方组件的集成测试,[13][17]介绍了详细的测试方法;
(3)我们研究的测试是针对检错进行的,确认软件是否正确实现了设计,协作图上的结构关系是否被正确实现,[15]中已有相应的静态检验方法,所以本文只研究动态交互行为的测试;
(4)本文为了明确解决问题,假定消息类型只有普通消息、条件消息、循环消息,而且只存在顺序循环,不存在嵌套循环。
3.2方法概述
基于协作图的集成测试(Collaboration diagram-based Integration Testing, CIT )方法集合了传统的白盒测试方法和黑盒测试方法,用于测试协作图中参与协作的对象之间通过消息的交互,对每个协作图处理一次,得到相应的测试用例集。首先分析协作图,提取协作图中表示的所有元素,根据消息的顺序号和消息的条件,找到每一条消息的直接后继消息,然后根据场景路径的定义,使用深度优先方法遍历消息及其直接后继直至到达无直接后继的消息从而生成场景路径,然后回溯到没有被访问的直接后继,重复上述方法找到所有的场景路径;在访问消息获取场景路径的同时,获取该路径的方法调用序列、参数和路径条件,将这些集成测试的关键因素用范畴-划分方法定义为方法序列、环境条件、系统输入、系统输出等范畴,结合该协作片断的用例规约和类图中的定义生成这些范畴的可能选择,然后结合路径约束条件在这些范畴的划分中确定选择项的合理组合,这样我们就等到了该场景路径完整的测试用例,包括外界输入、交互输入、预期方法调用序列、后条件、预期输出。对协作图中的所有场景路径都构造了测试用例,就形成了协作集成测试用例集。这样在实际执行集成测试时不但可以直接观察到系统级的输入作用下协作实现过程中的实际输出,还能够通过动态插装方法在代码中加入不影响软件功能的观察代码[15],使测试人员能够观察到实际协作执行时的方法调用序列和数据流的定义和使用,然后通过比较最终系统实际执行时输出与预期输出的一致性决定该协作实现的功能是否正确,通过比较应该发生的方法调用序列和实际执行时观察到的方法调用序列是否一致,确定协作表示的交互行为是否正确,从而从整体上对协作图描述的系统行为的实现是否与设计一致,从而完成协作的集成测试。
本方法可以以增量的方法进行,最终生成的测试用例的具体程度,与相应UML模型图的设计精化程度相关,因为协作图描述的场景的详细程度与测试用例的表达能力直接相关。
3.3 UML协作图生成测试用例的算法描述
本文的方法能够从协作图规约文档直接生成测试用例,主要描述分析协作图规约文档提取集成测试需求信息并生成消息后继表的算法UMLspecificationparser(),然后为每个消息确定其直接后继消息的findsuccessor()算法,根据消息后继表遍历所有场景路径获取测试用例规约信息的spathgenerator()算法,以及从测试用例规约使用范畴划分方法确定测试用例输入值、预期输出值、预期输出行为的算法testcasegenerator()。UMLspecificationparser()算法从协作图从获取集成测试需求信息是通过对UML协作图规约的文本文件(如Rational Rose 的MDL文件)进行分析完成的[11],在我们的工具中实现相应的功能,本文对分析算法不作详细描述。我们用邻接表定义消息后继列表,将分析结果信息按消息顺序号升序记录到messagelist的表头中,以便下一步处理。我们定义消息后继列表如下:
messageitem{
mid:string;//消息顺序号
mguardcondition:string;//消息卫式条件表达式
mlabel:string;//消息标签
msender,mreciever:object;// 消息发送者对象,消息接收者对象
mmethod:method;//消息激活的方法
mtype:[flat flow, procdure call, call return];// 根据消息的箭头及线型划分的消息类型
link:pointer of msuccessor;
}
msuccessor{
mid:string;//后继消息顺序号
mscondition:string;//选择该后继的条件表达式
next:pointer of msuccesor
}
messagelist:messageitem[n];
findsuccessor()算法为消息生成直接后继列表的并记录到消息的后继链表中,描述如下:
findsuccessor(messagelist){ //找到所有消息的所有可能后继和每个后继条件
//输入:消息后继表messagelist
//输出:消息后继表messagelist
//出口准则:所有消息都处理完
for i:=1 to n do {
if i= =n 或者messagelist[i]为端口输出事件触发消息
   messagelist[i].link=nil;i:=i+1; //最后消息或触发端口输出事件的消息无后继消息 
else{
if  messagelist[i+1]是普通消息
则messagelist[i]的直接后继为messagelist[i+1];
else{
k:=1;
do while  messagelist[i+k]是条件消息{
messagelist [i+k]是messagelist [i]的直接后继,且条件为messagelist [i+k]的条件取真
if messagelist [i+k]是循环或嵌套层次的第一个消息{
t:=该层次的消息数;messagelist [i+k+t]是messagelist [i]的直接后继;
条件为messagelist [i+k]的条件取假; k:=k+t;}//条件取假时循//环或嵌套内的消息都不发送
else{
messagelist [i+k+1]是messagelist [i]的直接后继;
条件为messagelist [i+1]的条件取假; k:=k+1;//不发送
}endif
}enddo
}endif
i:=i+1;
}endif
}endfor;
}endfindsuccessor;
spathgenerator()通过访问消息后继表中消息及其直接后继生成场景路径,在遍历场景路径时同时记录路径上相应的控制流和数据流信息,执行完毕得到一个场景路径集spath相应的控制流数据流测试规约。其算法描述如下:
s-pathgenerator(m:msuccessorlist){
//输入:messagelist; (消息后继表)
//输出:spath;(场景路径集)
spath{
sid:integer;//场景路径顺序号
pathcondition: list of gardcondition; //场景路径的实现条件
mlist:list of message;//场景路径上的消息流列表
parameters:list of variable;//场景路径上定义和使用的变量列表
userinputparameters: list of variable; //场景路径上外界输入参数列表
methodsequence:{objectname,methodname,next};场景路径上由消息激活的方法序列
}[n];
i,j:integer;
i:=1; j:=1;
Sid:=j;//场景路径序号
//递归访问消息及其直接后继
访问消息m,在消息标签中取出并记录返回值、参数、调用的对象方法;
记录消息条件到路径条件中;
if m的后继消息为空
{ 一条场景路径结束;j:=j+1;return;}//回溯到m[i]的直接前驱继续
else{
k:=1;
while m.link<>nil do { //m的后继消息列表不空
successor:=m.link;
spathgenerator(successor) //深度优先遍历该消息及其后继消息
m.link:=successor->next;//下一后继消息;
}endwhile
}endif;
}endfind;
testcasegenerator()选定遍历一个场景路径过程中生成的控制流和数据流,定义相关范畴,生成测试用例的规约。消息激活的方法序列正是我们要测试的对象间的交互,是软件执行时表现出来的对象之间的控制流传递行为,是对象之间通过消息交互的结果,定义为交互范畴Interaction Category;输入参数列表为测试该场景时外界的输入,定义为输入参数范畴input parameter Category;我们通过对参与协作对象的类图的分析,以及用例描述,可以获取我们所研究的交互行为定义、输入参数的定义、其他影响消息执行的变量的定义、系统环境条件的定义等,从而可以获取这些系统环境条件、输入参数、方法行为的可能选择,然后结合。
利用范畴-划分思想,用相应场景路径的路径条件和加在消息上的约束、以及系统本身的属性约束来限定这些选择,排除无意义和有冲突的值,然后通过这些不同的范畴的不同选择的可能组合作为一个场景路径的测试用例,这样每个场景路径生成一个集成测试用例。具体算法描述如下:
Testcasegenerator(){
//输入:spath[n]
//输出:tcsuite[n]{ envirnmentpara,input(inputpara,paravaliue),expectoutput,postcondition}
i:integer;
for i:=1 to n do {
tcsuite[i].postcondition:=spath[i].pathcondition;
tcsuite[i].environmentpara:={满足路径条件的环境条件}
tcsuite[i].input.inputpara=spath[i].userinputsparamenters;
选择对本场景路径条件有影响的参数确定其可能的取值;
tcsuite[i].input.paravalue={符合路径条件的输入参数可能的取值};
取出spath[i]的方法激活序列,分析每一个方法的定义,确定其可能的行为,选择符合场景路径条件的行为,并将方法序列的执行过程的输出序列存到tcsuite[i].expectoutput中;
i:=i+1;
}endfor;
}endtestcasegenerator;
为说明问题,我们选一条最长路径spath[5](消息序列为:1.1,1.2,2.1,2.2,2.3,4.1,4.2,4.3,5)来演示使用上述方法生成覆盖该路径的测试用例的过程。,从该路径获取相关范畴如下:
Tcsuite[5]
Pathcongdition:!notATMCard, !isStolen, !accountClosed, validPIN&&n=1,!declineFee
Environmentcondition:
ATM卡,非成员卡,卡没有被盗,帐户没有关闭
parameter category:
inputPIN     //影响validPIN  
123456 [property validPIN][if !notAtmCard]
564821 
123258
……..
deClineFee     //影响deClineFee
T   [property declineFee][if !isMemberCard]]
F
interaction behavior category:
session.beginSession(),     
插卡事件创建session对象
cardSlot.isATMCard(),
判断是ATM卡,读取卡号,定义cardNum,notATMCard=F[if !notATMCard]
判断不是ATM卡,notATMCard=T    
screen.prompt(),
屏幕提示“please input PIN”,n=1[if !notATMCard][property n]
屏幕提示“please input PIN”,n=2[if !notATMCard] [property n]
屏幕提示“please input PIN”,n=3[if !notATMCard] [property n]
numkeyPad.getEntry(),
输入正确的PIN inputPIN=’123456’[if n=1]
输入错误的PIN inputPIN<>’123456’[if n=1]
输入正确的PIN inputPIN=’123456’[if n=2] and [if !validPIN&&n=1]
输入错误的PIN inputPIN<>’123456’[if n=2] and  [if !validPIN&&n=1]
输入正确的PIN inputPIN=’123456’[if n=3] and [if !validPIN&&n=2]
         输入错误的PIN inputPIN<>’123456’[if n=3] and [if !validPIN&&n=2]
bank.checkCard(),
为被盗ATM卡验证PIN ,isStolen=T[if !notATMCard]
为帐户关闭的ATM卡验证PIN,accountClosed=T [if !notATMCard]
为合法ATM卡错误输入PIN验证身份,accountClosed=F, 
isStolen=F ,validPIN=F[if !notATMCard&n<4]
为合法ATM卡正确输入PIN验证身份,accountClosed=F, 
isStolen=F ,validPIN=T[if !notATMCard&n<4]
bank.getFeeAmount(),
获取非成员卡用户交易服务费金额,定义feeAmount [if !notATMCard&&ValidPIN&&n<4 and !isMemberCard]
screen.prompt() 
屏幕提示“Fee Payed:XXX”  
numkeyPad.getEntry(), 
输入同意付费,declineFee=T
输入拒绝付费,declineFee=F    
screen.prompt()
屏幕提示“please select transaction”[if !notATMCard&ValidPIN&&n<4] and [if isMemberCard or !isMembercard&!declineFee]
这样我们符合spath[5]路径条件的相应的一个测试用例tcsuite[5]的最后结果为:
Test case 5:
外部事件:插卡
environmentcondtion: ATM卡,非成员卡,卡没有被盗,帐户没有关闭
input category:
inputPIN=’123456’ //输入有效PIN
declineFee=F  //输入同意付费
interaction behavior category:
session.beginSession(),     
为ATM卡合法持卡人建立会话
cardSlot.isATMCard(),
判断是ATM卡,读取卡号cardNum, notATMCard=F
screen.prompt(),
屏幕提示“please input PIN”,定义n=1
numkeyPad.getEntry(),
输入正确的PIN,inputPIN=’123456’
bank.checkCard(),
为合法ATM卡正确输入PIN验证身份,定义accountClosed=F, 
isStolen=F ,validPIN=T,ismemberCard=F;
bank.getFeeAmount(),
获取非成员卡用户交易服务费金额,定义feeAmount=xxx
screen.prompt() 
屏幕提示“fee Payed XXX”
numkeyPad.getEntry(), 
输入同意付费  定义declineFee=F
screen.prompt()
屏幕提示“Please select transaction”
预期的方法调用序列:session.beginSession(),cardSlot.isATMCard() ,screen.prompt() ,numKeypad.getEntry() ,bank.checkCard()  ,bank.getFeeAmount(),screen. prompt (),numKeypad.getEntry(),screen. prompt () 
后条件:
inputPIN=’123456’,!notATMCard, !isStolen, !accountClosed, validPIN&&n=1,
!declineFee
预期输出:
屏幕提示“please input PIN”
屏幕提示“fee Payed XXX”
屏幕提示“Please select transaction”
我们可以用同样方法为属于同一个用例的其他协作图构造了测试用例,则该用例的集成测试集构造完成。然后,可以用增量方式为组件、子系统、系统构造完整的集成测试用例集,而且可以用自动的方式进行。可以用[15]中的插装方法按照每一场景路径上的方法调用顺序,对待测试实现进行插装,这样在执行时可以观察到软件用相应测试用例运行的结果,并将观察到的实际执行结果与测试用例中的预期结果进行比较,如果一致,说明相应场景的实现与设计是一致的,否则,存在错误,并且错误在协作图的相应场景路径上,可以通过实际结果与预期结果发生不一致的地方定位错误,然后调试修改。
3.3算法实现工具框架
为了支撑上述测试用例生成方法的自动化,我们设计一个基于UML设计模型图的集成测试用例的自动生成工具UMLTGF,我们仍然使用UML为UMLTGF建模,本文给出UMLTGF的类图,如图3。相应的功能描述如下:
1、UML模型分析器。能够直接读取UML协作图规约的文本文件(如MDL文件)[11],进行解析,并获取对象角色、对象的属性和方法,链、约束,消息流和消息标签,存入相应的中间表,以便测试用例生成器使用;
2、协作集成测试用例生成器。根据消息的顺序号和条件,跟踪消息流,生成每条消息的直接后继,然后通过遍历消息及其直接后继的方法生成协作图上每个用例场景对应的协作的场景路径,同时可以获取场景执行的控制流和数据流,并用范畴-划分方法生成相应场景路径对应的集成测试用例。输入为从协作图中提取的信息中间表,输出为生成的测试用例集合;
3、测试用例管理。为使得生成的测试用例集可复用、可维护、无冗余,对每个测试用例设计了增加、修改、删除操作,用来在测试用例生成过程中管理这些测试用例集。

                                                         图3 UMLTGF类图

4、相关工作
尽管UML在工业界和研究领域用得相当广泛,关于UML生成测试的研究相对较少。一般测试生成都是将UML模型图转换到一个现成工具能够处理的中间的形式化描述,从而可以处理UML规约。基于UML分析、设计模型获取系统的相关信息生成各个阶段的测试用例的研究近年来有不少成果,从设计阶段的模型图生成集成测试用例的研究较少,[13]提出一个新的基于UML的测试模型生成集成测试的测试用例的方法,该方法首先分析软件系统的顺序图和协作图,提取组件间的事件流,根据组件之间的消息转移将顺序图和协作图划分为一组原子系统功能(ASF)单元,以每个ASF为一个节点、消息流为边构造测试模型,使用面向对象的集成测试方法在测试模型上生成测试用例。
[12]提出基于UML设计规约生成集成测试用例的方法,用UML状态机图建立软件动态行为的模型,组件之间的交互用图上注解表示,将设计规约模型转化为与集成系统的动态行为相应的全局FSM,在FSM上基于一定的覆盖准则使用常规的等价类划分方法生成可用于单元和集成测试的测试用例。[14]提出一种不需要其他形式化知识、只在UML框架内完成测试用例生成的UIT方法,选择实现和执行每个用例图描述的功能的相应顺序图、协作图以及类图,分析图中元素的语义,识别出作为测试单元的参与交互的对象和与其相关的消息的等价类,定义测试规约,从图中找到消息顺序,使用传统的Category Partition Method分析消息顺序,生成最终的测试用例。[15]分析了UML规约级和实例级协作图中所能表示的信息,将信息进行分类,有些信息可以用于对最终程序的静态检查,有些信息可用于动态测试;并设计了一个根据协作图中信息对相应生成的程序进行插装的算法,实现对测试满足测试准则的程度的度量,但生成测试用例的方法还没有给出。[16] 提出了一个基于UML顺序图设计的面向对象的软件的自动测试的概念和相应的实现工具SeDiTeC。该方法提出一个可测试的顺序图的规则,凡是满足可测试性需求的软件系统的顺序图设计模型都可以作为测试规约,并介绍了从一个顺序图中生成测试用例的方法,在SeDiTeC中实现了完整的测试过程。
本文提出的从UML设计模型图(协作图、类图)生成集成测试用例的方法,可以对表示复杂场景的协作图进行处理,与上述方法是有一定区别,也是互补的。
5、总结和将来的工作
本文提出了一个基于UML协作图,采用协作集成测试模式生成集成测试用例的方法,用基于线程执行的方法识别协作图中的场景路径,用控制流和数据流方法遍历场景路径获取交互中的参数变量和方法调用序列,最后使用范畴-划分方法找到场景路径上的变量、方法、输入、输出、环境条件的合理组合作为覆盖该场景路径的测试用例;该方法的特点是:1、集合白盒方法和黑盒方法对协作图描述的灰盒行为进行测试;2、完全基于UML;3、生成较少的测试用例;4、便于实现自动化。
对基于UML生成测试用例的研究还存在许多不足。基于设计描述的形式化的测试准则相对还较少,基于UML模型图生成测试用例的方法也在不停的研究与发展中,目前对UML模型图作进一步精化或扩展其语义后,使用常规方法进行测试用例生成的情况较多,直接使用UML模型图提供的信息的方法较少;把单个模型图作为研究对象的较多,多个模型为同一测试用例生成提供信息的研究较少;针对测试过程中特定级别的测试(类级测试、集成测试)生成测试用例的方法较多,同一模型图为多个级别测试生成测试用例的研究较少;在具体的方法研究中,假设的前提和约束太多,还不能够达到实用的程度;对方法提供自动支持的工具大多是实验室原型,还不能应用到工业界;可应用的领域还有许多局限;缺少整体的、系统的解决方法,还没有能够把待测试系统的所有能够为测试用例生成提供信息的模型图综合利用,形成一个系统的测试用例生成方法,这也正是我们将来的研究方向。
我们将来的研究工作主要有几个目标:第一,提出一种与面向对象软件开发过程集成的测试过程,测试用例应以增量、系统的、与项目成本和进度相适应的可管理的数目的方法产生,利用业务模型生成用户验收测试的测试用例,利用UML分析模型生成系统测试的测试用例,利用UML设计模型生成集成测试的测试用例,利用实现模型生成单元测试的测试用例,能够合理计划测试资源,并能够对软件开发过程起到过程改进的作用;第二,针对UML单个模型图,研究其在为不同层次测试生成测试用例的方法,提出相应可行的测试准则和评估方法,尽量能够直接使用UML模型文档;第三,针对某一层次测试的测试用例生成时,研究综合利用待测试系统的各种模型图生成该测试层次的测试用例的方法;第四,为上述方法提供自动的工具支持,并希望能够与主流建模工具、测试工具集成。

 

参考文献:
[1]Imran Bashir, Amrit L. Goel, Testing Object-oriented Software: Life Cycle Solution[M],Springer-Verlag New York, Inc 1999
[2]David C.Kung, Pei Hsia, Jerry Gao, Testing Object-oriented Software[C], IEEE Computer Society,1999
[3] Beizer. Black-box Testing:Techniques for functional testing of software and systems[M], John Wiley&Sons,Inc, New York 1995
[4]Paul C. Jorgrnsen, Software Testing: A Craftsman’s Approach [M], CRC Press,Inc, 1995
[5]UML Specification 1.5[S], available at http://www.omg.org/uml
[6]Grade Booch, James Rumbaugh, Ivar Jacobson著 邵维忠等译  UML 用户指南[M], 机械工业出版社,Addison-Wesley 2001
[7]Grade Booch, James Rumbaugh, Ivar Jacobson著,姚淑珍,唐发根等译,UML 参考手册[M],机械工业出版社,Addison-Wesley 2001
[8]Grade Booch, James Rumbaugh, Ivar Jacobson著,周伯生,冯学民,樊东平 译,统一的软件开发过程[M], 机械工业出版社,Addison-Wesley 2001
[9]Robert V. Binder著 华庆一 王斌君 陈莉 译 面向对象系统的测试[M], 人民邮电出版社2001
[10]Philippe Kruchten, The Rational Unified Process –An Introduction[M], 2nd edition, Addison-Wesley, Reading, MA, 2000
[11]A. J. Offutt and A. Abdurazik, “Generating Tests from UML specifications,”[C] Proc. 2nd International Conference on the Unified Modeling Language (UML'99), Fort Collins, CO, pp. 416-429, October, 1999. 
[12]Hartmann, J., Imoberdof, C., Meisenger, M., "UML-Based Integration Testing", [C]in ISSTA 2000 conference proceeding, Portland, Oregon, 22-25 August 2000, pp. 60-70.
[13] Byoungju Choi, Hoijin Yoon, Jin-Ok Jeon, "A UML-based Test Model for Component Integration Test,"[C] Workshop on Software Architecture and Component, Japan, pp63-70, 1999.12
[14]Basanieri, F., Bertolino, A.: A Practical  Approach  to UML-based  Derivation  of Integration Tests.[C] Proceeding of QWE2000, Bruxelles, November 20-24, 3T.
[15]A. J. Offutt and A. Abdurazik, “Using UML Collaboration Diagrams for Static Checking and Test Generation,”[C] Proc. 3rd International Conference on the Unified Modeling Language (UML'00), York, UK, pp. 383-395, October, 2000.
[16] Falk Fraikin, Thomas Leonhardt,Sequence diagram based test automation,[R]http://www.pi.informatik.tu-darmstadt.de/publikationen/technische%20Berichte/2002/pi2002-2.pdf
[17]Ye Wu, Mei-Hwa Chen and Jeff Offutt, "UML-based Integration Testing for Component-based Software",[C] The 2nd International Conference on COTS-Based Software Systems (ICCBSS). pages 251-260, Ottawa, Canada, February 2003.