注意,图1中的试验模型被稍微简化以提供一个测试模型中的一些核心要素的例子。测试这样一个系统的真实模型将包含更多步骤,动作和检查,以及更多的规定。例如,我们需要来启动和终止调动的步骤,注销终端步骤,移动它们的网络的步骤,启动数据传输不同类型的步骤,等等更多。
至于这种模型中的规定,我们应该保持终端列能有效调用,消息列可以发送和接收,并保证一切有效数据传输。并且应在测试先知中用类似于图1中检查注册终端的方式去再次坚持这项新规定。本文的其余部分将把示例模型引用为一个扩展版本。一个测试生成器可采取不同的方法从一个测试模型生成测试用例。对于OSMO Tester生成器及图1所示测试模型,该模型可能如[ ACM ]所述那样被直观地描述为一系列规则和动作。该模型定义了一组可以在被测系统上进行的动作(在OSMO Tester标记中用作@TestStep的一部分)。当这些动作中的每一个都被允许时,一组规则(OSMO Tester标记中的@Guard)定义了。规则允许的话,生成器以不同的方式组合这些动作以生成测试用例。整个测试模型可以被视作用来描述大量的可能测试用例集。随后测试生成器从(使用一些由用户定义的覆盖准则的)这个模型去生成测试用例。可用标准的变化取决于所使用的工具,但一些例子包含了在模型中覆盖用户指定要求(手动标记的特定部分或路径),覆盖动作组合,并覆盖不同动作的各种数据值。(可能已被用来为我们的示例模型指导生成器的)覆盖准则的一些例子包括:注册终端的数量,调用终端的数量,注册却自由(不处于调用状态)的终端的数量,及动作结果配对。例如,它可以被定义为对将“零”,“一”和“多”类别都覆盖到终端类型数中的每一个很感兴趣。动作覆盖可以与这些数值中的一些进一步配对,以激励生成器来生成步骤,诸如注销一个调用终端和注销一个不同配置下的非调用终端。有了更严格/松散的覆盖目标,以及从自由度变为在测试用例中添加随机性,那么生成机可以被用来生成一组更小/更大的测试用例。
图2是一个(含有图1模型中的一个测试生成流程的四个不同点的)例子。在点一( 1 )中 ,模型程序被5个未注册终端初始化了。在点二(2 )中,生成由几个步骤推进,且三个终端已被注册。在点三( 3 )中 ,几个步骤再次被通过且两个注册终端有了有效调用(两者间的单独调用)。在点四( 4 )中,两个以前未注册的终端已经被注册了,前面调用的一部分已经退出,已用两个终端建了一个新的调用。
图2.测试生成流程示例
它真正测试哪些东西呢?
测试生成的一个常见问题是:它真正测试什么呢?如果我们只是无休止地生成测试数据或测试步骤却对结果的正确性一无所知,那还有什么意义呢?在基模测试中,测试模型也可以用来检查测试用例。图1中这是由模型中@Post注释的方法举例说明的。生成器在所有的测试步骤两两间(后)执行这个过程,以证明被测系统的情况与测试模型的情况一致。例如,在图2的点二( 2 )中,它会检查是否测试模型中被标记为注册的三个终端在被测系统中也都处于相同情况。它还要检查其他两个没有被注册,而且他们都没有正在进行有效调用。
类似地,更具体的检查可以嵌入到任何可在其中获得一些具体结果的行动中去。
如果需要的话,这些检查可以是不同粒度的,且可以在按量进行,因为不像手工脚本,他们不需要手工编写每个测试用例的每一步,却可以由测试生成器进行,时间间隔与时间长短都不限。
当已经创建了一个测试模型,测试生成器用来从这些模型生成测试用例。除了用指定的覆盖准则为指导从整体模型生成测试,很多MBT工具还提供了一种手段来指导生成器用各种形式的用户定义场景去关注特定部分。例如,有了(有调用等的)扩展示例模型,我们或许还想从某个角度专注分析管理终端注册的网络服务器。要做到这一点,用户可以创建一个场景,确保只有测试步骤与该场景(如注册和注销)相关联。
工具的具体场景定义语言,可以用来建立这样的场景。要建一个特定测试配置,测试模式可用指定终端实例被参数化。
图3说明了为我们只允许注册和注销步骤的示例模型建立一个场景,且每个步骤都必须在每个生成的测试用例中出现至少两次。
更真实的例子会包括更多步骤,更多部分,并且可能还包括用以驱动SUT到场景起点的启动脚本。
这样一个场景甚至可以用来定义一个特定动作序列,该序列将被用作一个启动脚本以生成一个类似于手工编写测试用例的纯手工特定测试用例,而不是当模型和其他生成的测试用例一样变化时将被更新。
图3.使用OSMOTester的场景定义示例