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]