计算机科学丛书
点击查看第二章
点击查看第三章
基于模型的测试:一个软件工艺师的方法
The Craft of Model-Based Testing
[美] 保罗·C.乔根森(Paul C. Jorgensen) 著
王轶辰 王轶昆 曹志钦 译
第1章
基于模型测试概述
无论是软件还是硬件,甚至是日常生活中,所有的测试都可以视为系统因某个激励产生响应,然后对其进行检查的过程。事实上,早期的需求方法也主要是针对激励-响应进行研究的。在基于模型的测试(MBT)中,我们认为模型在某种程度上就是激励-响应的一种表达方式。其中有一些说明性的词汇有助于我们对这个问题的理解。
在软件测试领域,有3种被广泛接受的测试级别:单元测试、集成测试和系统测试。每个级别的测试都有明确的测试目标和测试方法。单元测试主要针对类或者过程进行测试,集成测试主要针对单元之间的交互进行测试,而系统测试则更加关注被测系统(SUT)的对外端口(也称为端口边界)。每个级别的测试都有一个测试覆盖矩阵(更详细的讨论请见[Jorgensen 2013]),同时每个级别的测试用例都包含相似的要素:用例名称和标识(ID)、前置条件、输入序列(也可能是交互输入)及预期输出、记录的实际输出、后置条件,以及通过准则。
1.1 基本术语
定义:被测系统通常缩写为SUT,即将要被测试的系统。
SUT可能是:一个由软件控制的硬件系统,一个仅有硬件的系统或者仅有软件的系统,甚至可能是由若干个SUT组成的大系统。SUT也可以是一个单独的软件单元或者是由多个单元组成的集合。
定义:被测系统的端口边界,是被测系统中所有能够施加输入激励以及接收输出响应的端口集合。
无论是硬件、软件还是固件抑或是3种的组合,每一类系统都有端口边界。识别出SUT“真正的”端口边界对于基于模型的测试(MBT)过程而言是至关重要的。为什么说是“真正的”?因为在测试过程中我们很容易将用户引起的物理事件与由此产生的电子信号(激励)相混淆。在基于Web的应用中,用户接口很可能就是系统级的输入和输出所在位置。在汽车刮水器控制器中,端口边界通常包括控制杆、决定刮水器速度的拨盘以及驱动刮水器叶片的电机。本书中还用到了车库门控系统(后面会详述),该系统的端口边界包括发送控制信号的设备、安全设备、末端传感器,以及一个驱动电机。一个单元的端口边界则是激活该单元的某种机制(可能是面向对象软件中的消息,也可能是传统软件中的某个过程调用)。
定义:端口输入事件是针对给定SUT端口边界的一个激励。同样,端口输出事件是发生在SUT端口边界的一个输出响应。
在看待系统的端口输入事件上,开发人员和测试人员在观念上有明显的不同。测试人员的想法是针对SUT如何产生或引发一个输入激励,而开发人员考虑更多的是输入激励会导致软件产生什么样的行为和动作。这种区别也同样明显地反映在输出事件上,测试人员需要知道如何观察或者探知到系统的输出响应,而开发人员则关心如何生成或者引发输出响应。这些观念上的不同,有一部分是由软件开发团队构建的设计和开发模型所造成的。设计和开发模型是从开发者的视角进行构建的,而测试用例的产生却是从测试人员的视角构建的。这个不同之处可能会在基于模型的测试中产生一定的影响。
1.2 事件
下面的术语基本上都是同义词,但略有不同:端口输入事件、激励、输入。同样,下面这些词也基本上算是同义词:端口输出事件、响应、输出。事件是一级一级发生的,当然,或许使用“按顺序发生”会更好些。我们来看车库门控系统(见1.8.2节详述),重点是包含光束传感器的安全设备。当车库门正在向下关闭的时候,如果任何事物阻断了光束(在靠近地板部分),那么电机会立刻停止并反向打开车库门。这个事件序列就是从某一个物理事件开始的,这个事件有可能是向下关门过程中有一个小动物恰巧穿过了光束。当光束传感器探测到中断时,它会给控制器发送一个信号。这就是端口输入事件,而且是一个真实的电信号。内部的控制器软件就会将此视为一个逻辑事件。
端口输入事件可能发生在不同的逻辑场景中。“一只猫穿过了光束”是一个物理事件,而这个物理事件有可能发生在好几种场景中,例如车库门已经打开的时候,正在打开车库门的时候,或者正在关闭车库门的时候。我们所关心的逻辑事件却只是发生在“正在关门”的时候。通常,事件发生环境在某些有限状态机(FSM)中表示为状态。在评估不同类型的模型对MBT的支持能力的时候,有一个很重要的指标就是该类型的模型能否表达和识别出对环境敏感的输入事件。同样,这也要求我们关注端口输入设备本身。假设一个测试人员想要测试光束传感器,尤其是其失效模式。通常的设备失效包括“在位置1失效”(SA-1)和“在位置0失效”(SA-0)。对于SA-1失效,光束传感器在发送信号位置失效,即保持一直发送信号的状态,无论物理输入事件有没有发生。请注意,在这种失效情况下是没法关上车库门的(请见下表中的EECU-SA-1用例)。而SA-0失效更加隐蔽一些,它表示光束传感器始终保持不发送信号的状态,这将导致即使物理中断发生之后,门也不会反向打开。我相信,如果律师得知在安全设备中会产生SA-0失效之后,那么他一定会非常郁闷。在第8章我们会对此进行建模。
“在某个位置失效”这类故障以及其他失效模式是很难被定义的。它们可能不会出现在需求文档中。就算是在需求文档中有所说明,在很多基于模型测试的过程中也很难对其进行建模。我们会在第8章详述这一点。用户有可能会提供类似EEUC-SA-1的用例吗?基于以往的经验,这是很有可能的。但在敏捷开发中,这就是个挑战了。
1.3 测试用例
对于一个测试用例而言,它有两种基本的形式—抽象的和真实的,有些MBT团队将后者称为具体测试用例。抽象测试用例通常是从一个形式化模型中派生出来的。何为抽象?意指输入通常是以变量方式来表达的。真实的(具体的)测试用例包含输入变量的真实数值,以及预期的输出数值。这两种形式都包括前置和后置条件。
1.4 测试用例的执行框架
图1-1是一个通用的自动化测试用例执行框架。它的基础是我的团队在20世纪80年代早期开发的一个针对电话交换机系统的回归测试项目。图中的计算机包括所有测试用例的处理器,这些处理器控制并观察测试用例的执行过程。测试用例使用简单的语言来描述,这个语言可以解释执行。语言中包括CAUSE和
VERIFY语句,它们指代SUT的端口边界。CAUSE语句一般都带有参数,它们指代端口输入事件和发生这些事件的设备(它们还可能有附加参数)。同样,VERIFY语句指代预期的端口输出事件。在电话交换机的SUT中,一个测试用例可能有以下两种语句:
在这些语句中,InputDigit指代Line12设备上发生的带有参数的端口输入事件以及该设备上发生的端口输出事件。能够实现这个框架的关键是开发一个能够连接SUT与测试用例处理器的“?套件?”。套件主要完成的工作包括以下内容。在CAUSE语句中,将端口输入事件从逻辑形式(抽象形式的用例)转换为物理形式;在VERIFY语句中,将端口输出事件从物理形式转换为逻辑形式。
以上内容主要针对系统级测试。在单元测试中,类似nUnit family的自动测试工具很常见,其中CAUSE和VERIFY语句被ASSERT语句替代。ASSERT语句中包括被测单元的输入和输出,由此取代了系统测试中的测试套件。本书中我们忽略了集成测试,因为几乎没有MBT工具能够支持集成测试。本章结尾部分给出的MBT例子也只是包括了单元测试和系统测试。大家一定要记住,基于模型的测试要想成功,使用的模型必须能够提供激励和响应,不管它是单元级别还是系统级别。
1.5 MBT中的模型
软件和系统设计模型通常包含两种类型—针对结构的模型和针对行为的模型。在通用建模语言(UML)中(UML已经成为一种事实上的标准),针对结构的模型集中于类、类的属性、方法和类之间的连接(继承、聚合、相关)。另外,主要有两种针对行为的模型—状态图和活动(或者顺序)图。本书第一部分呈现了9种针对行为的模型:流程图、决策表、有限状态机、Petri网、事件驱动的Petri网、状态图、泳道型事件驱动的Petri网、UML(用例和活动图)、业务流程建模和标识(BPMN)。在这些模型中,除了泳道型事件驱动的Petri网[Jorgensen 2015]和BPMN以外,都在[Jorgensen 2008]中有非常详细的解释。本书的重点是扩展这些模型,以支持基于模型的测试。在MBT中有一个不可避免的局限性,只有原生模型(软件和系统设计模型)比较好,派生出来的测试用例才能够同样好。因此在第一部分我们需要特别关注的就是不同模型的局限性以及它的表达能力。
1.6 ISTQB中的MBT扩展
本书意在与ISTQB基础级大纲中关于MBT的内容保持一致,该大纲于2015年10月发布。ISTQB(国际软件测试评定委员会)是一个非营利组织,截止到2013年,已经有超过100个国家的336?000名测试人员取得认证。本书的第二部分介绍了6个测试工具,以及使用这些工具对书中的例子进行测试的结果。
1.7 MBT的形式
基于模型测试的过程有3种基本形式:手动测试、半自动测试和全自动测试[Utting 2010]。在手动MBT中,构建并分析SUT的模型是为了设计测试用例。例如,在基于有限状态机的MBT过程中,首先需要使用有限状态机对SUT进行建模,这样一条从初始状态到最终状态的路径就可以被形象地标识出来并转化成测试用例。接着需要确定一个可用准则,用来选择哪些测试用例将予以执行。这些选择测试用例的准则实质上就是某些覆盖矩阵。然后我们还需要对这些用抽象术语描述的测试用例进行“?具体化?”(这是一个在MBT领域常用的术语)。比如,将“?个人ID号码?”这种抽象表达具体化为一个真实的数值“?1234?”。最后一步是在被测系统上执行具体的测试用例。这部分内容可以参考Craig Larman [Larman 2001],资料中提到了用例的4个级别(第9章会详述)。其中第三级称为扩展的关键用例,包含了抽象的变量名;而Larman的第四级用例就是真实使用的用例,将抽象的术语和变量名称替换为要测试的真实数值。这就是具体化过程。半自动MBT和手动MBT的区别是在测试过程的早期是否使用了工具。工具是指能够运行某个合适模型并且生成抽象测试用例的引擎。下一步,从生成的测试用例集中挑选予以执行的测试用例,这个过程可以自动进行也可以手动进行。在有限状态机例子中,挑选测试用例的准则可能是以下几种:
1)覆盖所有状态。
2)覆盖所有变迁。
3)覆盖所有路径。
这个挑选过程也可以自动进行。另外,全自动MBT与半自动MBT的区别是测试用例是否自动执行,我们在第二部分会详述这一过程。
1.8 案例集
1.8.1 单元级问题:保费计算
政策规定的汽车保费是根据考虑了成本的基本利率计算而成的。该计算的输入如下所示:
1)基本利率是600美元。
2)保险持有者的年龄(16≤年龄< 25;25≤年龄< 65;65≤年龄<?90)。
3)小于16岁或者大于90岁的,不予保险。
4)过去5年中出险次数(0、1~3和3~10)。
5)过去5年出险次数超过10次的,不予保险。
6)好学生减免50美元。
7)非饮酒者减免75美元。
具体数值的计算见表1-1~表1-3。
1.8.2 系统级问题:车库门控系统
车库门控系统包括驱动电机、能够感知开/关状态的车库门轮传感器以及控制设备。另外,还有两个安全设备:地板附近的光束传感器和障碍物传感器。只有车库门在关闭过程中,后面两个安全设备才会运行。正在关门的时候,如果光束被打断(可能家中的宠物穿过)或者车库门碰到了一个障碍,那么门会立即停止动作,然后向反方向运行。为减少后续章节中的模型数目,本书中我们只考虑光束传感器。关于障碍物传感器的分析,与之基本相同,不再赘述。一旦门处于运行状态(要么正在打开,要么正在关闭),控制设备发出信号,门就会停止运行。后续的控制信号会根据门停下来时的运动方向来起动门的运行。最后,有些传感器会检测到门已经运行到了某个极限位置,即要么是全开,要么是全关。一旦这种情况发生,门会停止动作。图1-2是车库门控系统的SysML上下文图。
在绝大多数的车库门控系统中,有如下几个控制设备:安装在门外的数字键盘、车库内独立供电的按钮、车内的信号设备。为简单起见,我们将这些冗余的信号源合并为一个设备。同样,既然两个安全设备产生同样的响应,我们只考虑光束设备,忽略障碍物传感器。
1.8.3 其他案例
这里给出其他几个案例以说明和比较建模理论和技术。表1-4描述了表1-5中的示例使用的不同的建模方式。
1.9 MBT的技术现状
从20世纪80年代起,MBT就以手动的方式开始为人所用。此后许多学术研究团队开发的开源MBT工具,让更多的人开始关注MBT。最近,商用MBT工具的出现使得这项技术进入到工业领域。从Robert V. Binder所做的两份调查中可以看出使用MBT的一些原因。最早针对MBT用户的调查是在2011年开展的,随后在2014年又做过一次。这些调查总结了早期MBT使用者的期待与顾虑。
Binder在2011年的调查[Binder 2012]中特别强调了以下几点:
- MBT的应用有了长足发展,包括软件过程、应用领域和开发团队方面。
- MBT不仅可用而且可行。一半的被访者反馈说,只需要80小时或者更少的时间就可以基本熟练掌握MBT技术,80%的受访者需要最多100小时。
- 平均来说,受访者反馈MBT技术能够减少59%的错误逃逸率。
- 平均来说,受访者反馈MBT技术能够减少17%的测试开销。
- 平均来说,受访者反馈MBT技术能够减少25%的测试时间。
该调查项目在2014年再次开展,同时增加了两个MBT的实践者:Anne Kramer(见第18章)和Bruno Legeard(见第14章)[Binder 2014]。此次一共收到100份反馈。下述内容显示了此次调查的亮点(内容为直接引用或者部分引用)。
测试级别:
- 77.4%的人使用MBT进行系统测试
- 49.5%的人使用MBT进行集成测试
- 40.9%的人使用MBT进行验收测试
- 31.2%的人使用MBT进行部件测试
生成的产品:
- 84.2%的产品是自动的测试脚本
- 56.6%的产品是手动测试用例
- 39.5%的产品是测试数据
- 28.9%的产品是其他文档
最大的益处:
- 测试覆盖率
- 处理复杂度
- 自动测试用例的生成
- 重用模型和模型元素
最大的局限性:
- 工具支持
- 需要专门的MBT技能
- 不愿意改变
通用观察:
- 96%的人在功能测试中使用MBT
- 81%的人使用图形化模型
- 59%的人针对行为特性建模
- 大概需要80小时成为熟练用户
- 72%的参与者非常愿意继续使用MBT
MBT用户的期待:
- 73.4%的人期待更高效的测试设计
- 86.2%的人期待更有效的测试用例
- 73.4%的人期待更好地管理系统测试的复杂性
- 44.7%的人期待改进交流
- 59.6%的人期待尽早开始测试设计
MBT的整体效率:
- 23.6%非常有效
- 40.3%中等有效
- 23.6%稍微有效
- 5.6%几乎无效
- 1.4%效率轻微下降
- 2.8%效率中等下降
- 2.8%效率极度下降