带你读《基于模型的测试:一个软件工艺师的方法》之二:流程图

简介: 本书主要讨论基于模型的测试(MBT)技术。作为一门手艺而非艺术,其关键在于:对被测软件或系统的理解,选择合适工具的能力,以及使用这些工具的经验。围绕这三个方面,书中不仅综合阐述了MBT的理论知识及工具,而且分享了作者的实战经验。

点击查看第一章
点击查看第三章

第2章

流程图
计算机领域很早就开始使用流程图(flowchart)了,这可能是使用最早的一类行为模型。在20世纪60年代,工具供应商通常会提供一些具有可塑性的流程图模板,程序员可以据此绘制出更整齐的流程图。IBM公司甚至提供了一个带有基本标记的不同规格标准的流程图模板。前辈们开玩笑说,这是该领域的第一个CASE(计算机辅助软件工程)工具。

2.1 定义与表示法

通常有两种不同风格的流程图标记形式。图2-1所示为第一种,这是一种极简风格的表示方式,只有表示动作、决策和两种页连接符的符号。分页连接符一般用于不能在一页上显示完全的大型系统中。传统的分页连接符使用大写字母ABC…,第一个分页连接符是A,与之对应的连接点也用A表示。
在流程图使用的早期,因为比较关心系统的输入/输出设备,所以开发出很多扩展的流程图符号,如图2-2所示,这里面甚至有表示卡片式I/O的符号。
 

image.png

在这种流程图标记方式中,“?流?”的部分使用带箭头的线段,表示从某个流程图符号开始,在某个流程图符号处结束。图2-3是特浓咖啡自动售卖机的流程图示例,利用这个咖啡机,可以用1欧元买到一小杯意大利特浓咖啡。后续我们还会使用这个案例讨论流程图技术。

2.2 技术详解

图2-3中的流程图能够处理自动售卖机的销售过程。接收欧元硬币,给出特浓咖啡。如果仔细观察流程图,可能会注意到,所有的箭头都会在符号的顶部结束。这不是强制要求,但这样做有助于理解。决策框只能有一个入口,既然是决策过程,那么至少应有两个出口箭头。在早先的Fortran年代,“Arithmetic IF”语句带有3个输出。这个钻石形状的框(决策符号框)的边与底部顶点可以分别表示3种选择(<、=、>)。在图2-3中很容易看到这3个选项。如果多于3个选项(比如Case/Switch语句),每个选项对应一个连接箭头即可。(标识符是为使用者服务的,不必非要遵守条条框框)。过程框则最多只有一个输出箭头。但它们可能有多个输入箭头。箭头上的标签通常表明决策框有几个可能的出口,Yes/No、True/False或者数值显示决策结果。从过程框发出的箭头则没有标签。这样表示过程框的过程是完整的,流程走向下一个框。框之间不会表达信息或内容。使用者需要自己确定过程框的结果对于后续框是否可用(流程图具有“记忆性”)。

image.png

对于过程框和决策框来说,框内文本内容几乎没有限制,可以有不同的形式,这些形式的抽象程度也可以不同。框内文本可以简明扼要,如图2-3所示。或者也可以非常具体,甚至可直接是某种编程语言。例如“硬币是”决策框的输出结果可以是1.00欧元、0.50欧元或0.20欧元三种形式。同样,决策条件也可以表示为针对每一种硬币类型的二进制条件,如“是”或“否”。不管使用哪种方式,最好要保持一致,如果不同抽象级别的文本表达混合在一起,那将是很让人困惑的。流程图的符号集可以支持结构化编程的3种基本结构:顺序、选择、循环。例如图2-3所示的决策框表示了“选择”结构,而图2-3底部还有一处表示了“循环”结构:如果变量“总金额”与1欧元的比较结果是“小于”,就会返回到投入硬币过程框。再看一下1欧元那个分支,它结束“提供特浓咖啡”这个过程框,这正是“顺序”结构的例子。在结构化编程中,通常有“单一入口,单一出口”的设计惯例,但是这个惯例并不是强制要求,图2-3所示例子是符合这个惯例的。
流程图采用分层策略来处理不同抽象级别的过程。也就是说,一个高抽象级别的过程框可以扩展成一系列更详细、单独的流程图。如果这样做,那么每一个低抽象级别的流程图都应该被命名,以此来清晰地表明它是从某个高抽象级别的过程框扩展而来的,或者干脆使用分页连接符(只是分页连接符的方式显得有些笨重)。本章结束部分的表2-4,总结了在流程图中可以表达的控制事件。

2.3 案例分析

2.3.1 日期计算函数

NextDate函数是测试圈里非常流行的一个例子,它非常简单,很容易找到测试用例的预期输出。(给定某个日期,NextDate函数返回下一个日期。)图2-4和图2-5采用分层流程图方式将功能进行了分解。变量lastDay的数值通过其他方式计算出来,然后与决策框中的日期进行比较。如果某个变量可以在多处赋值,那么必须保证最终计算出来的数值在运行过程中不会相互改写。在NextDate流程图中,有3个值被分配给nextDay、nextMonth和nextYear。决策框要求这3个赋值必须是互斥的。在这些计算过程中使用到了GoTo语句,当使用流程图来建立主要的行为模型时,使用GoTo语句是一种常用作法。在流程图中可以清晰地看到,NextDate函数的逻辑是很严密的。

image.png

2.3.2 风寒指数表

著名的风寒指数(密歇根州或者其他寒冷地区)是由两个变量构成的函数:每小时风速V和摄氏温度T。其公式如下所示:
image.png
其中,W是人脸的表面温度,以华氏度为单位;T是空气温度,以华氏度为单位,
-20≤T≤50;V是风速,以mile/h(1mile?=?1609.34m)为单位,3≤V≤73。
基于图2-6所示的流程图可以完成一个类似表2-1的表格,请注意其中的循环嵌套。

image.png

image.png

(例子中的数值范围是随意制定的,在密歇根州,这是真实情况!)风寒表格中温度的范围是-20℉≤T≤50℉,每次递增5℉;风速范围是3≤V≤73,每次递增5mile/h。

2.3.3 保费计算流程图

图2-7是1.8.1节中定义的保费计算问题的流程图模型。

2.3.4 车库门控系统流程图

图2-8是1.8.2节中定义问题的流程图模型。

image.png

image.png

2.4 基于流程图派生的测试用例

流程图中的路径可以直接推导出抽象的测试用例。由于流程图可以显示并发的路径,因此很容易手工设计出相关的抽象测试用例。从图2-7所示的保费计算流程图中可以看到关于年龄和保费变量的并发路径。毫无疑问,并发路径应该是互斥的。(测试用例也可以利用某个指定流程图的语义内容派生出来,但这反过来又要求手动推导测试用例生成。)通常来说,从流程图中不可能直接设计出具体的测试用例,因为流程图只显示了需要完成的过程,并不实际执行这些过程。
(对于类似Fortran这样的程序来说,流程图很好用。)而对于事件驱动型应用来说,流程图的形式就显得不太适合了。从接下来给出的事件驱动示例,可以清晰看出以下几个问题。

  • 事件可以表示为决策的输出或者过程(过程框)。
  • 由于没有专门的事件标识符,所以事件只能表示为流程图中有明确语义的内容。
  • 需要具有洞察力和领域经验才能识别与上下文相关的输入事件。

2.4.1 保费计算问题的测试用例

图2-7所示的流程图中一共有40条不同的路径,其中36条对应着表2-2列出的使用等价类测试方法生成的测试用例。年龄和出险次数变量由变量的取值范围来定义,因此从表面上看,只需要测试某种形式的边界值就足够充分了。将每个等价类中的边界值映射到相同的乘法和加法函数集合中,它们会在结果中产生大量的冗余,因而这并无太大价值。图2-9显示了表2-2中测试用例1的路径。
表2-2显示了保费计算问题的抽象测试用例和具体测试用例。抽象测试用例可以从流程图中直接设计出来(MBT工具可以完成这个过程)。实际数值则需要从需求中获取。从图2-7中给定的文本可以看出,对于MBT工具来说,直接生成测试用例需要的实际数值还是很困难的。我主要使用电子表格中的替换功能来完成这部分工作,这样还不算太麻烦。通常来说,电子表格是MBT工具很顺手的一个补充。
下面是图2-8所示路径对应的测试用例1中的抽象和具体测试用例。

image.png

image.png

image.png

2.4.2 车库门控系统的测试用例

在车库门控系统的流程图中有两个循环:一个是停下并重启正在关闭的门,另一个是停下并重启正在打开的门。(一个是在关门过程中停下或者重启,一个是在开门过程中停下或者重启。)如果假设输入事件和输出过程是同时发生的,那么数学家会说,在图2-8所示的流程图中,存在一个含有不同路径的可数无穷路径集合。在实际生活中,我家的车库门需要大概13s关闭或者开启,而停止/重启序列需要大概1s,因此,实际上车库门流程图只有一个有限数目的可能路径。图2-10显示了其中一条路径,该路径由下面的测试用例来表示。图2-10所示的流程图符号是有编号的,以表示路径的追踪和命名。

image.png

表2-3包含车库门流程图中的5条不同路径。我们先简要描述一下每条路径(也可以视之为用户场景),然后再使用按系列编号的流程图符号来详细描述它们。5条路径涵盖了每个流程图符号和流程图中的每条边。另外还有些路径是针对光束被打断之后的过程的,这些路径也包括每个上下文的控制设备的输入事件。对于工具来说,很难从流程图中设计出详细的、类似使用用例(use case,从用户角度考虑的使用场景)的测试用例。

image.png

image.png

表2-4包括从图2-8所示流程图中设计出的手工测试用例信息。从中我们可以看出,流程图的定义存在一些“小问题”,原因如下:
1)输入事件看上去既可以是决策框的输出,也可以是过程框中表示的一个过程;
2)事件上下文(状态)看上去是与过程框对应的过程,也可以说是决策框的输出;
3)有两个潜在的死循环:正在开门或者关门时停止。
除非具有领域经验,否则,利用输入事件/输出过程对是没有办法定位下一步操作的。

2.5 优势与局限

流程图有很多优势。如果任何一种表达方式已经使用了数十年,那么它肯定还是有可取之处的。对于流程图来说,这个优势就很容易理解。由于过程框和决策框里面的文本可以使用自然语言,因此流程图使客户和开发者之间具有更好的交互性。就连美国的IRS都是用流程图来解释复杂的税务代码的。如我们之前所说,流程图能够表达基本的结构化编程架构。其中,还有没有明确说明的地方,这就是对于流程图中“存储器”功能的使用。如果一个变量在过程框中被赋予一个值,那么该变量在后续需要保持这个数值。在图2-3中可以清楚地看到,变量“总金额”被定义之后,在之后的循环中可以再次定义它。任何“形式化好的”流程图都可以使用命令式和结构化的编程语言进行编码。如示例中所示,流程图支持几种级别的抽象,因此它们具有可扩展性,能够描述大型而且复杂的应用。另一个优势是,它们可以用来描述复杂的计算和算法。最后一个优势是有些控制过程或者行为可以通过流程图中不同的路径来表达。

image.png

流程图也有些限制。由于流程图的本质是将过程序列化,所以很难表达事件驱动的系统,因为在事件驱动的系统里面,独立事件可能以任何顺序发生。此外,流程图很难描述被描述系统需要操作的外部设备的上下文。虽然面向设备的I/O符号可以完成这个工作,但是需要很多扩展。流程图几乎没有办法表达数据,除非是在过程框或者I/O框里面。过程框和决策框里面的文本可以包含变量名,但这是很粗浅的表达。数据表达都如此困难,表达数据结构以及数据之间的关系就更难了。同样,对于描述事件,它也有很多潜在的困难。从图2-8中可以看到,设备控制信号有时表示为过程框,有时又显示为决策框的输出。表2-5将流程图的描述能力与第1章定义的标准列表进行了对比。

image.png
image.png

2.6 经验教训

在20世纪60年代晚期,电话交换机系统开发实验室需要将所有的交互系统源代码的流程图文档提供给运营公司。当时,源代码大概是30万行的汇编程序。在这个过程中,软件工程师需要向图案部提交手绘流程图,六周以后,软件工程师就可以得到非常完美的流程图。在这六周内,如果设计师想要对流程图进行修改,那么他们可以将原始草图替换成修改之后的草图,以免在图案部里重新排队。
同时,我的管理团队中的一位数学家参加了一次研讨会,会上他看到一个程序,这个程序能够在CalComp绘图机上画出离散部件电路图。我们研究了技术资料后,决定将电路图符号替换成流程图符号,结果就产生了AELFLow系统[Jorgensen和Papendick 1970]。这是我们学到的第一个经验:为了使绘图机能够得到认可,我们向每个部门展示了他们如何从绘图机上获益。推销了几周之后,我们最终得到许可购买了最小的绘图机。6个月之后,我们有了最大的绘图机。AELFlow系统非常有效,不仅节约了返工的时间,而且提高了设计文档的整体可用性。相比汇编代码,流程图更容易从技术角度进行描述。从各方面来看,AELFlow系统都是真正的CASE工具,这比术语CASE的使用要早得多。
这里关键的教训是:变革是很难引入的,它需要时间、耐心和对企业的认知,同时也需要培训。尽管对于AELFLow系统来说,培训是很少的一部分。Gartner Hype的周期是相当精确的,尽管持续的间隔可能有变化(如图2-11所示)。准备引入MBT的组织一定要经历宣传周期。我的观点是,期望膨胀的峰值期源于MBT产品的销售团队,泡沫破裂的幻灭期则源于不同模式的不充分的培训和教育。稳步爬升的复苏期开始于合适的工具和良好的模式教育,实质生产的成熟期则随着市场的关注度和占有率而保持。

image.png

参考文献

image.png

相关文章
|
18天前
|
测试技术 API 项目管理
API测试方法
【10月更文挑战第18天】API测试方法
34 1
|
30天前
|
机器学习/深度学习 人工智能 监控
提升软件质量的关键路径:高效测试策略与实践在软件开发的宇宙中,每一行代码都如同星辰般璀璨,而将这些星辰编织成星系的过程,则依赖于严谨而高效的测试策略。本文将引领读者探索软件测试的奥秘,揭示如何通过精心设计的测试方案,不仅提升软件的性能与稳定性,还能加速产品上市的步伐,最终实现质量与效率的双重飞跃。
在软件工程的浩瀚星海中,测试不仅是发现缺陷的放大镜,更是保障软件质量的坚固防线。本文旨在探讨一种高效且创新的软件测试策略框架,它融合了传统方法的精髓与现代技术的突破,旨在为软件开发团队提供一套系统化、可执行性强的测试指引。我们将从测试规划的起点出发,沿着测试设计、执行、反馈再到持续优化的轨迹,逐步展开论述。每一步都强调实用性与前瞻性相结合,确保测试活动能够紧跟软件开发的步伐,及时适应变化,有效应对各种挑战。
|
17天前
|
测试技术 UED
软件测试中的“灰盒”方法:一种平衡透明度与效率的策略
在软件开发的复杂世界中,确保产品质量和用户体验至关重要。本文将探讨一种被称为“灰盒测试”的方法,它结合了白盒和黑盒测试的优点,旨在提高测试效率同时保持一定程度的透明度。我们将通过具体案例分析,展示灰盒测试如何在实际工作中发挥作用,并讨论其对现代软件开发流程的影响。
|
1天前
|
机器学习/深度学习 人工智能 自然语言处理
自动化测试的新篇章:利用AI提升软件质量
【10月更文挑战第35天】在软件开发的海洋中,自动化测试犹如一艘救生艇,它帮助团队确保产品质量,同时减少人为错误。本文将探索如何通过集成人工智能(AI)技术,使自动化测试更加智能化,从而提升软件测试的效率和准确性。我们将从AI在测试用例生成、测试执行和结果分析中的应用出发,深入讨论AI如何重塑软件测试领域,并配以实际代码示例来说明这些概念。
20 3
|
2天前
|
测试技术 开发者 Python
自动化测试之美:从零构建你的软件质量防线
【10月更文挑战第34天】在数字化时代的浪潮中,软件成为我们生活和工作不可或缺的一部分。然而,随着软件复杂性的增加,如何保证其质量和稳定性成为开发者面临的一大挑战。自动化测试,作为现代软件开发过程中的关键实践,不仅提高了测试效率,还确保了软件产品的质量。本文将深入浅出地介绍自动化测试的概念、重要性以及实施步骤,带领读者从零基础开始,一步步构建起属于自己的软件质量防线。通过具体实例,我们将探索如何有效地设计和执行自动化测试脚本,最终实现软件开发流程的优化和产品质量的提升。无论你是软件开发新手,还是希望提高项目质量的资深开发者,这篇文章都将为你提供宝贵的指导和启示。
|
8天前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
13 2
|
12天前
|
编解码 人工智能 自然语言处理
迈向多语言医疗大模型:大规模预训练语料、开源模型与全面基准测试
【10月更文挑战第23天】Oryx 是一种新型多模态架构,能够灵活处理各种分辨率的图像和视频数据,无需标准化。其核心创新包括任意分辨率编码和动态压缩器模块,适用于从微小图标到长时间视频的多种应用场景。Oryx 在长上下文检索和空间感知数据方面表现出色,并且已开源,为多模态研究提供了强大工具。然而,选择合适的分辨率和压缩率仍需谨慎,以平衡处理效率和识别精度。论文地址:https://www.nature.com/articles/s41467-024-52417-z
36 2
|
15天前
|
敏捷开发 监控 jenkins
自动化测试之美:打造高效的软件质量保障体系
【10月更文挑战第20天】在软件开发的海洋中,自动化测试如同一艘精准的导航船,引领项目避开错误的礁石,驶向质量的彼岸。本文将扬帆起航,探索如何构建和实施一个高效的自动化测试体系,确保软件产品的稳定性和可靠性。我们将从测试策略的制定、工具的选择、脚本的编写,到持续集成的实施,一步步描绘出自动化测试的蓝图,让读者能够掌握这一技术的关键要素,并在自己的项目中加以应用。
25 5
|
15天前
|
Java 测试技术 持续交付
探索自动化测试的奥秘:提升软件质量的关键
【10月更文挑战第20天】 在当今快速发展的软件行业中,自动化测试已成为确保产品质量和加速开发周期的重要工具。本文将深入探讨自动化测试的核心概念、实施策略及其对软件开发生命周期的影响,旨在为读者提供一种全面理解自动化测试的视角,并展示如何有效地将其应用于实际项目中以提高软件质量和效率。
17 2
|
1月前
|
测试技术
谈谈【软件测试的基础知识,基础模型】
谈谈【软件测试的基础知识,基础模型】
24 5
下一篇
无影云桌面