一个描述用例实现的实例级协作图上用于建模的元模型包括:类元角色名、关联角色名、对象符号、链接符号、消息符号、链上的约束等。对象框能够表示参与协作中交互的对象,链表示这些对象之间的结构关系,消息的箭头形状表示协作对象间的通信模式和对象的执行特征, 消息标签表示对一个对象的操作调用的允许顺序的实例、操作的语义。在实际的建模活动中有些元素并不在模型上反映,例如图1的协作图只表示了协作中参与的对象和对象之间的消息,这是表示对象交互的最小元素集。本文关注协作图表示的动态行为的测试,前面提到协作图上表示交互的主要元素是消息,下面详细介绍消息。
协作图中的消息用带有消息标签的箭头表示,附在连接发送者和接受者的链上,链用于访问目标对象,箭头沿着链指向接受者,一个链上可以有多个消息,沿着相同或不同方向传递,消息的相关顺序由消息标签中的顺序号表示。按照UML1.5[5]中提出消息箭头有三种形状表示对象之间的通信方式和控制流类型:实线实心箭头表示同步消息,用于表示过程调用和嵌套控制流,每次调用增加一个嵌套层次;刺状箭头表示平面控制流,是异步通信,无嵌套,表示前驱-后继关系,指向下一步骤;虚线刺状箭头表示从过程调用返回。图1中的消
图1 ATM建立一次会话的实例的协作图
息都是带有刺状箭头的实线,表示前驱/后继关系。消息标签说明发送的消息、发送的条件、由消息激活的方法、相应的参量和返回值,以及交互中的消息顺序,包括调用嵌套、迭代、分支、并行和同步,完全格式消息标签的语法[5]中有详细的定义。其语法如下:
[predecessor][guardcondition][sequence-expression][return-value-list]:=message-name(argument)
[predecessor]表示前驱,在协作中前驱是用逗号隔开的顺序号列表,并后跟“/”;[guardcondition]表示线程同步的卫式条件;[sequence-expression]表示顺序项列表每一项表示交互中的一个嵌套层次,如果所有的控制并行则无嵌套;整数表示过程调用中的相邻高层中的消息的顺序,同一整数项中的不同消息在嵌套层是顺序相关的,同一前缀的消息顺序号构成序列。循环表示条件或迭代执行,表示根据条件执行零个或多个消息;[return-value-list]在有返回值的情况下表示消息返回值的名称,名称之间用逗号隔开,可以作为后续消息的参量;message-name 表示目标对象中引发的事件名称,可以用不同的方式实现,如操作调用;Argument 是消息引发的方法的参量列表。
图2 图1 ATM用户验证的类图
消息上的条件增加了消息的表达能力,也增加的消息复杂度,消息上的条件有几种形式:在一个新的调用层次开始,如图1中消息标签4.1[isMemberCard]feeAmount:=getfeeAmount()所示:4.1表示一个新的调用序列,条件成真时该层次的消息顺序发送,否则都不发送;在顺序发送的消息上,例如消息1.3中,[!isATMCard]条件表示二值条件,条件成真时其后的消息eject()执行一次,否则不执行,对其他消息没有影响;在一个表示迭代的嵌套调用消息开始,如消息3.1.1表示了一个迭代执行多个消息的情况,根据validPIN和n的取值可能发送1或2次消息。
这些协作图上的模型元素所表示的软件系统的不同方面的信息,都是系统的本质信息,需要在软件从设计到实现过程中必须保持的,因而软件实现中的行为的本质方面都会在设计中表示,所以可以从设计表示中获取行为方面的信息,用于确认软件实现中是否正确实现。
2.2场景路径
一个表示用例实现的协作图实现了用例的不同事件流,包括正常流和异常流,每个事件流称为一个场景,这些场景都被相应的协作图实现。一个协作图所表示的协作正是从一个外部事件触发开始,在参与协作的对象之间完成一系列的交互,最后正确的协作结束时都导致一个外部输出 ,对应于一个实际场景,也是一个线程执行的路径。要找到这些路径,一般的方法是将协作图转换为流图,然后在流图上使用图遍历的方法达到路径覆盖从而得到所有的路径。本文为了避免复杂流图的转换和不可行路径的遍历开销,试图直接从协作图上获取这些路径。我们从Paul C. Jorgenson[4]定义原子系统功能(ASF)和方法/消息路径(MM-path)得到启发,本文定义了一个场景路径(scenario-path):
定义 场景路径(scenario-path,s-path)是协作图上从一个没有前驱消息的消息开始,沿着消息的偏序执行序列,到达一个没有后继的消息结束的由消息相连的方法执行序列。