软件评测师-12.测试用例设计方法

2023-09-25 14 0

12.测试用例设计方法

12.1测试用例的基本概念

12.1.1测试用例的概念

测试用例是一个关于具体测试步骤的文档,描述了测试的输入参数、条件以及配置,以及预期的输出结果等,以判断被测软件的工作是否正常。

它可以是纯文本的说明文档,也可以是用脚本语言或高级语言编写的一段代码。

其中应该包括用例名称、目标、测试条件、环境、测试设置、输入数据要求、步骤、以及预期结果等参数。

12.1.2测试用例的分类

测试用例体现了测试设计者的方案、方法、技术和策略,分为两大类。

(1)正面测试用例:用于验证需求已经得到满足的测试用例

(2)负面测试用例:反映某个无法接受、反常或意外的条件或数据,用于论证只有在所需条件下才能够满足该需求。

测试用例是软件测试的核心,其决定了测试过程的质量

12.2测试分类的方法及概念

12.2.1按照测试用例设计的角度的测试的分类

12.2.1.1黑盒测试与白盒测试的概念

从测试用例设计的角度,可以分为黑盒测试、白盒测试和灰盒测试

(1)黑盒测试

把测试的对象看做一个黑色的盒子,根据测试软件产品的功能来设计测试用例。而测试人员不需要关心软件产品的内部结构和处理的过程,因此黑盒测试又称为“功能测试”或“数据驱动测试”

(2)白盒测试

把测试的对象看做一个透明的盒子,允许测试人员利用逻辑结构和有关信息设计和选择测试用例测试程序所有的路径。通过在不同检查点检查程序的状态,确定实际状态是否与预期一致,因此白盒测试又称为“结构测试”或“逻辑驱动测试”

(3)灰盒测试

测试人员在已经了解软件功能的源代码的基础上进行的功能以及界面测试

12.2.1.2黑盒测试与白盒测试的检查点

黑盒测试主要测试的错误类型:

(1)不正确或遗漏的功能

(2)接口及界面错误

(3)性能错误

(4)数据结构错误或外部数据访问错误

(5)初始化或终止条件错误等

白盒测试的目的如下:

(1)保证一个模块中的所有独立路径至少被执行一次

(2)对所有逻辑值均需要测试真假两个分支

(3)在上下边界以及可操作范围内运行所有循环

(4)检查内部数据结构以确保其有效性

12.2.1.3黑盒测试与白盒测试的比较

黑盒测试与白盒测试各有优缺点,通常在软件测试中综合使用,下表为两者的比较

表12-2  黑盒测试和白盒测试的比较

类别

优点

缺点

黑盒测试

(1)代价较低,容易上手

(2)对测试人员的要求相对较低,不需要了解软件实现的细节和编程语言

(3)从用户的视角测试,容易被理解和被接受

(4)有助于暴露于规格不一致或者有歧义的问题

(1)只有少量的可能的输入数据被测试

(2)如果没有清晰的简明的规格,测试用例很难设计

(3)会有很多程序路径未被测试

(4)不能直接针对特定程序段测试,该程序段可能隐藏更多错误

白盒测试

(1)测试人员会思考软件的实现

(2)可以检测代码中的每条分支和路径

(3)揭示隐藏在代码中的深层次错误

(4)对代码的测试比较透彻

(1)代价比较高

(2) 对测试人员的要求相对较高,需要了解软件实现的细节和编程语言

(3)无法检测代码中遗漏的路径和数据敏感性错误

(4)不直接验证规格的正确性

12.2.2按照测试执行方式的角度的测试的分类

按照测试执行方式的角度的测试的分类可以分为静态测试和动态测试

(1)静态测试:指不运行被测程序本身,仅通过分析或检查程序的文法、结构、过程和接口参数来检查程序的正确性。

(2)动态测试:指通过运行被测程序检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能,这种方法通常由3个部分组成:即构造测试用例、执行程序和分析程序的输出结果

12.2.3测试工具

12.2.3.1白盒测试工具

白盒测试工具针对代码进行测试,测试中发现的缺陷可以定位到代码级。根据测试工具原理不同,又可以分为静态和动态测试工具

(1)静态测试工具:直接分析代码,不需要运行代码。

常用的静态测试工具有Telelogic公司的Logiscope软件和和PR公司的PRQA软件

(2)动态测试工具:采用“插桩”方式,在代码生成的可执行文件中插入一些监测代码,用来统计程序运行时的数据。

常用的动态测试工具有Compuware公司的Devpartner软件和和Rational公司的Purify系列软件等

12.2.3.2黑盒测试工具

黑盒测试工具适用于黑盒测试的场合,一般原理是利用脚本的录制(Record)/回放(Playback)功能模拟用户的操作,然后将被测系统的输出记录下来与预先给定的标准结果比较。该工具可以大大减轻黑盒测试的工作量,在迭代开发过程中能够很好的进行回归测试。

黑盒测试工具可以分为功能和性能测试工具两类,长剑的黑盒测试工具一般都兼有功能和性能测试的作用。

黑盒测试工具的代表有Compuware公司的QAcenter软件和和Rational公司的Teamtest软件和Robot软件等,LoadRunner是一种适合于各种体系架构的自动负载测试工具,能预测系统行为并优化系统性能

12.3测试用例设计方法的概念、特点、适用范围及选取策略

常用的黑盒测试用例设计方法有等价类划分法、边界值分析法、错误推测法、判定表驱动分析法、因果图法、正交试验法、功能图分析法和场景法等。常用的白盒测试用例设计方法有基本路径法和逻辑覆盖法

12.3.1等价类划分法

等价类划分是把所有可能的输入数据,即程序的输入域划分成若干部分(子集),然后从每一个子集中选取少数具有代表性的数据作为测试用例。在等价类划分法设计测试用例的过程中,需要使用两个过程:分类和抽象。第一个过程是分类,即将输入域按照具有相同特性或者类似功能进来分类;第二个过程抽象,即在各个子类中抽象出相同特性并用实力来表征这个特性。

12.3.2边界值分析法

边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充,这种情况下,其测试用例来自等价类的边界。

12.3.3错误推测法

错误推测法能充分发挥人的直觉和经验,在一个测试小组中集思广益,方便使用,特别是在软件测试基础较差的情况下,很好地组织测试小组进行错误猜测,是一种有效的测试发放。但错误推测法不是一个系统的测试方法,所以只能用作辅助手段,即先用其他方法设计测试用例,再用此方法补充一些例子。这种方法的优点是测试者能够快速且容易地切入,并能够体会到程序的易用与否;缺点是难以知道测试的覆盖率,可能丢失大量未知的区域,并且这种测试行为带有主观性且难以复制。

12.3.4判定表驱动分析法

因果图方法中已经用到了判定表(Decision Table),它是分析和表达多逻辑条件下执行不同操作的情况下的工具。在程序设计发展的初期,判定表就已被当做编写程序的辅助工具了。由于判定表测试严格,能够将复杂的逻辑关系和多种条件组合的情况表达得既具体又明确,针对不同的逻辑条件组合值,分别执行不同的操作,因此,使用判定表能够设计出完整的测试用例集合。判定表是一种针对存在条件、动作关系或者因果关系的特性测试的用例设计方法。

12.3.5因果图法

错误推测法是根据经验和直觉设计测试用例,尽管能考虑到输入组合的情况,但仍显得不充分。因果图法则借助图形来设计测试用例,特别适用于被测程序具有多种输入条件,程序的输出又依赖于输入条件的各种组合的情况。

因果图法着重分析输入条件的各种组合,每种组合条件就是“因”,它必然有一个输出的结果,这就是“果”。等价类法与边界值分析法的缺点是没有检查各种输入条件的组合,而因果图就能有效地检测输入条件的各种组合可能引起的错误。它是一种形式语言,由自然语言写成的规范转换而成,这种形式语言实际上是一种使用简化记号表示数字逻辑图。它还能指出程序规范中的不完全性和二义性。

12.3.6正交实验法

正交实验法就是利用排列整齐的表(正交表)来对试验进行整体设计、综合比较、统计分析,实现通过少数的实验次数找到较好的生产条件,以达到最高生产工艺效果。正交表能够在因素变化范围内均衡抽样,使每次试验都具有较强的代表性,由于正交表具备均衡分散的特点,保证了全面实验的某些要求,这些试验往往能够较好或更好的达到实验的目的。正交实验设计包括两部分内容:第一,是怎样安排实验;第二,是怎样分析实验结果。

12.3.7功能图分析法

一个程序的功能说明通常由动态说明和静态说明组成.动态说明描述了输入数据的次序或转移的次序.静态说明描述了输入条件与输出条件之间的对应关系.对于较复杂的程序,由于存在大量的组合情况,因此,仅用静态说明组成的规格说明对于测试来说往往是不够的.必须用动态说明来补充功能说明.功能图方法是用功能图FD形式化地表示程序的功能说明,并机械地生成功能图的测试用例. 功能图模型由状态迁移图和逻辑功能模型构成.状态迁移图用于表示输入数据序列以及相应的输出数据.在状态迁移图中,由输入数据和当前状态决定输出数据和后续状态.逻辑功能模型用于表示在状态中输入条件和输出条件之间的对应关系.逻辑功能模型只适合于描述静态说明,输出数据仅由输入数据决定.测试用例则是由测试中经过的一系列状态和在每个状态中必须依靠输入/输出数据满足的一对条件组成.功能图方法其实是是一种黑盒白盒混合用例设计方法。

12.3.8场景法

通过运用场景来对系统的功能点或业务流程的描述,从而提高测试效果。场景法一般包含基本流和备用流,从一个流程开始,通过描述经过的路径来确定的过程,经过遍历所有的基本流和备用流来完成整个场景。

为什么场景法能如此清晰的描述整个事件?因为,现在的系统基本上都是由事件来触发控制流程的。如:我们申请一个项目,需先提交审批单据,再由部门经理审批,审核通过后由总经理来最终审批,如果部门经理审核不通过,就直接退回。每个事件触发时的情景便形成了场景。而同一事件不同的触发顺序和处理结果形成事件流。这一系列的过程我们利用场景法可以清晰的描述清楚。

12.3.9逻辑覆盖法

逻辑覆盖是通过对程序逻辑结构的遍历实现程序的覆盖,可以分为以下7种覆盖:

语句覆盖SC (Statement Coverage)、

判定覆盖 DC (Decision coverage)、

条件覆盖CC (Condition Coverage)、

条件/判定覆盖 CDC(Condition/ Decision Coverage)、

多条件覆盖(条件组合覆盖) MCC(Multiple Condition Coverage)、

修正条件/判定覆盖 MCDC(Multiple Condition Decision Coverage)、

路径覆盖PC(Path Coverage)

12.3.10基本路径法

基本路径测试法是在程序控制流图的基础上,通过分析控制构造的圈复杂性,导出基本可执行路径集合,从而设计测试用例的方法。设计出的测试用例要保证在测试中程序的每个可执行语句至少执行一次。

在程序控制流图的基础上,通过分析控制构造的圈复杂性,导出基本可执行路径集合,从而设计测试用例。包括以下4个步骤和一个工具方法:

(1)程序的控制流图:描述程序控制流的一种图示方法。
(2)程序圈复杂度:McCabe复杂性度量。从程序的圈复杂性可导出程序基本路径集合中的独立路径条数,这是确定程序中每个可执行语句至少执行一次所必须的测试用例数目的上界。
(3)导出测试用例:根据圈复杂度和程序结构设计用例数据输入和预期结果。
(4)准备测试用例:确保基本路径集中的每一条路径的执行。

12.4等价类划分法

12.4.1等价类划分法的定义和划分

在进行等价类划分的过程中,不但要考虑有效等价类划分,同时需要考虑无效等价类划分。有效等价类和无效等价类定义如下:

(1)有效等价类:是指输入完全满足程序输入的规格说明,有效、有意义的输入数据所构成的集合。利用有效等价类可以检验程序是否满足规格说明所规定的功能和性能。

(2)无效等价类:和有效等价类相反,即不满足程序输入要求或者无效的输入数据构成的集合。使用无效等价类,可以鉴别程序异常情况的处理。在程序设计中,不但要保证所有有效的数据输入能产生正确的输出,同时需要保障在输入错误或者空输入的时候能有异常保护,这样的测试才能保证软件的可靠性。

12.4.2等价类划分法的原则和方法

基于上面的描述,在等价类划分时,使用以下的几个原则:

(1)在输入条件规定了取值范围或者个数的前提下,可以确定一个有效等价类和两个无效等价类。例如:程序输入条件为满足小于100大于10的整数x,则有效等价类为10<x<100,两个无效等价类为x<10和x>100。

(2)在输入条件规定了输入值的集合或者规定了“必须如何”的条件下,可以确定一个有效等价类和一个无效等价类。例如:程序输入条件为x=10,则有效等价类为x=10,无效等价类为x≠10。

(3)在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类。例如:程序输入条件为BOOL x=true,则有效等价类为x=true,无效等价类为x=false。

(4)在规定了一组输入数据(包括n个输入值),并且程序要对每一个输入值分别进行处理的情况下,可确定n个有效等价类和一个无效等价类。例如:程序输入条件为x取值于一个固定的枚举类型{1,3,7,10,15},则有效等价类为x=1,x=3,x=7,x=10,x=15,而程序中对这5个数值分别进行了处理,对于任何其他的数值使用默认Default处理方式,此时无效等价类为≠1,3,7,10,15的值的集合。

(5)在规定了输入数据必须遵守的规则的情况下,可确定一个有效等价类和若干个无效等价类,例如输入是页面上用户输入有效E-mail地址的规则,必须满足几个条件,含有@,@后面格式为x.x,E-mail地址不带有特殊符号”、#、‘、&。有效等价类就是满足所有条件的输入的集合,无效等价类就是不满足其中任何一个条件或者所有条件的输入的集合。

(6)在确定已知的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步划分为更小的等价类。

12.4.3等价类划分法的设计步骤和过程

在使用等价类做测试用例设计时,按照划分好的等价类,

(1)为每个等价类规定一个唯一的编号。

(2)设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这个过程,直至所有的有效等价类都被覆盖,即分割有效等价类直到最小。

(3)设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的无效等价类,重复这个过程,直至所有的无效等价类都被覆盖,即分割无效等价类直到最小。

12.5边界值分析法

12.5.1边界值分析法的基本概念

实践证明,程序往往在输入输出的处理边界情况下发生错误。边界情况指输入等价类和输出等价类边界上的边界,检查边界情况的测试用例是比较高效的,可以查出更多的错误。

12.5.2边界值分析法遵循的原则和方法

边界值分析法就是在某个变量范围的边界上,验证独立的输入/输出是否正确的测试方法。

边界值分析法取决于变量的范围和范围的类型,确认所有输入的边界条件或临界值,然后选择这些边界条件/临界值及其附近的值来进行相关功能的测试。边界值分析法处理技巧有:

(1)如果输入条件规定了值的范围,则取刚达到这个范围的边界值,以及刚刚超过这个范围边界的值。

(2)如果输入条件规定了值的个数,则用最大个数、最小个数、比最大个数多1个、比最小个数少1个的数等作为测试数据。

(3)根据规格说明的每一个输出条件,使用前面的规则(1)。

(4)根据规格说明的每一个输出条件,应用前面的规则(2)。

(5)如果程序的规格说明给出的输入域或输出域是有序的集合(例如有序表,顺序文件等),则应选取集合的第一个和最后一个元素作为测试数据。

(6)如果程序用了一个内部结构,应该选取这个内部数据结构的边界值作为测试数据。

(7)分析规格说明,找出其他可能的边界条件。

12.5.3边界值分析法的实例

这里给出测试一个排序程序的边界值分析法的例子,其边界条件有:

(1)排序序列为空。

(2)排序序列仅有一个数据。

(3)排序序列为满,用猜错法补充一下测试用例。

(4)排序序列已经按要求排好序。

(5)排序序列的顺序与要求的顺序恰好相反。

(6)排序序列中的所有数据全部相等。

因为错误最容易发生在边界值附近,所以边界值分析法对于多变量函数的测试很有效,尤其是对于像C/C++这种数据类型要求不是很严格的语言有用。缺点是对布尔值或逻辑变量无效,也不能很好地测试不同的输入组合。边界值分析法也不具有随机性,常被看做是等价类划分法的一种补充,两者结合起来使用更有效。

12.5.4边界值分析法的数值取值

为了更准确的表达边界值分析法中的数值取值,定义以下几个概念:

(1)内点:在域范围内的任意一点

(2)上点:边界上的点(无论是开区间还是闭区间)。如果该域是封闭的,则上点就在域的范围内;如果该域是开放的,则上点就在域范围外

(3)离点:离上点最近的点。如果该域是封闭的,则离点就在域的范围外离上点最近的那个点;如果该域是开放的,则离点就在域范围内离上点最近的那个点

表12-3  边界上的上点和离点的示例

区间

边界

上点

离点

[0,100]

左边界

0

-1

右边界

100

101

(0,100)

左边界

0

1

右边界

100

99

12.6因果图法

因果图法是从程序的规格说明的描述中找出因果关系,通过因果图转换为判定表。利用图解法分析输入的组合情况,从而设计测试用例的方法,它适合于检查程序输入条件的组合情况

12.6.1因果图的画法

因果图中使用了简单的逻辑符号,以直线联接左右结点。左结点表示输入状态(或称原因),右结点表示输出状态(或称结果)。ci表示原因,通常置于图的左部;ei表示结果,通常在图的右部。ci和ei均可取值0或1,0表示某状态不出现,1表示某状态出现。

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130238412-1828232666.png

12.6.2因果图中的基本概念

12.6.2.1因果图中的关系逻辑

因果图中的关系逻辑有4种,分别如下:

(1)恒等:若ci是1,则ei也是1;否则ei为0。

(2)非:若ci是1,则ei是0;否则ei是1。

(3)或:若c1或c2或c3是1,则ei是1;否则ei为0。“或”可有任意个输入。

(4)与:若c1和c2都是1,则ei为1;否则ei为0。“与”也可有任意个输入。

 12.6.2.2因果图中的约束逻辑

输入状态相互之间还可能存在某些依赖关系,称为约束。例如,某些输入条件本身不可能同时出现。输出状态之间也往往存在约束。在因果图中,用特定的符号标明这些约束。因果图中的约束逻辑有5种,分别如下:

A.输入条件的约束有以下4类: 

(1)E约束(异):a和b中至多有一个可能为1,即a和b不能同时为1。 
(2)I约束(或):a、b和c中至少有一个必须是1,即 a、b 和c不能同时为0。 
(3)O约束(唯一):a和b必须有一个,且仅有1个为1。 
(4)R约束(要求):a是1时,b必须是1,即不可能a是1时b是0。
B.输出条件约束类型有以下1类:
(5) M约束(强制):输出条件的约束只有M约束,若结果a是1,则结果b强制为0。

因果图中的约束逻辑如下图所示:

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130302521-1164587307.png

12.6.3因果图法设计测试用例的步骤

因果图法设计测试用例的步骤如下:

1.分析待测得系统规格,找出原因与结果

分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件), 并给每个原因和结果赋予一个标识符。
2.画出因果图

分析软件规格说明描述中的语义。找出原因与结果之间,原因与原因之间对应的关系。根据这些关系,画出因果图。
3.标记约束或限制条件

由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况下不可能出现。 为表明这些特殊情况,在因果图上用一些记号表明约束或限制条件。
4.把因果图转换为判定表。
5.用判定表中的每一项生成测试用例。

12.7判定表驱动法

12.7.1判定表的概念

因果图方法中已经用到了判定表(Decision Table),它是分析和表达多逻辑条件下执行不同操作的情况下的工具。在程序设计发展的初期,判定表就已被当做编写程序的辅助工具了。由于判定表测试严格,能够将复杂的逻辑关系和多种条件组合的情况表达得既具体又明确,针对不同的逻辑条件组合值,分别执行不同的操作,因此,使用判定表能够设计出完整的测试用例集合。判定表是一种针对存在条件、动作关系或者因果关系的特性测试的用例设计方法。

表12-7  判定表的示意图

列1

列2

列3

列4

条件桩

条件项1

条件项2

条件项3

条件项4

动作桩

动作项1

动作项2

动作项3

动作项4

12.7.2判定表的组成

判定表通常由4个部分组成:

1)条件桩(Condition Stub):列出了问题的所有条件,列出条件的次序没有约束。

2)动作桩(Action Stub):列出问题规定可能采取的操作,这些操作的排列顺序无关紧要。

3)条件项(Condition Entry):列出条件桩给出的条件并列出所有可能的取值。针对条件桩的条件和条件项的取值,判断在整个程序模块中的所有可能的情况下其结果的真假值。

4)动作项(Action Entry):列出在条件项的各种取值情况下应该采取的动作。

12.7.3判定表的建立步骤

判定表的建立步骤如下:

1)确定规则的个数,

例如,有n个条件,那么决策表中就有2n个规则(每个条件取真、假值)。

2)列出所有的条件桩和动作桩。

3)填入条件项。

4)填入动作项,得到初始判定表。

5)简化判定表,合并相似规则。

12.8正交实验法

正交实验法就是利用排列整齐的表(正交表)来对试验进行整体设计、综合比较、统计分析,实现通过少数的实验次数找到较好的生产条件,以达到最高生产工艺效果。正交表能够在因素变化范围内均衡抽样,使每次试验都具有较强的代表性,由于正交表具备均衡分散的特点,保证了全面实验的某些要求,这些试验往往能够较好或更好的达到实验的目的。正交实验设计包括两部分内容:第一,是怎样安排实验;第二,是怎样分析实验结果。

正交实验的原理如下图:

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130341709-554394151.png

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130403256-2063055491.png

12.9场景法

12.9.1场景法的相关概念

12.9.1.1场景法的基本定义

现在的软件几乎都是用事件触发来控制流程的。象GUI软件、游戏等。事件触发时的情景并形成了场景,而同一事件不同的触发顺序和处理结果就形成了事件流。这种在软件设计方面的思想可以引入到软件测试中,可以生动地 描绘出事件触发时的情景,有利于设计测试用例,同时使测试用例更容易理解和执行。

在测试一个软件的时候,在场景法中,测试流程是软件功能按照正确的事件流实现的一条正确流程,那么我们把这个成为该软件的基本流;而凡是出现故障或缺陷的过程,就用备选流加以标注,这样的话,备选流就可以是从基本流来的,或是由备选流中引出的。所以在进行图示的时候,就会发现每个事件流的颜色是不同的。

12.9.1.2场景法的基本流和备选流

基本流和备选流:

(1)基本流:如下图所示,图中经过用例的每条路径都用基本流和备选流来表示,直黑线表示基本流,是经过用例的最简单的路径。

(2)备选流:备选流用不同的色彩表示,一个备选流可能从基本流开始,在某个特定条件下执行,然后重新加入基本流中(如备选流1和3);也可能起源于另一个备选流(如备选流2),或者终止用例而不再重新加入到某个流(如备选流2和4)。

基本流和备选流的示意图如下:

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130421693-575000033.png

12.9.2场景法的场景设计

每个经过用例的可能路径,可以确定不同的用例场景。从基本流开始,再将基本流和备选流结合起来,可以确定以下用例场景:

(1)场景1:基本流

(2)场景2:基本流、备选流1

(3)场景3:基本流、备选流1、备选流2

(4)场景4:基本流、备选流3

(5)场景5:基本流、备选流3、备选流1

(6)场景6:基本流、备选流3、备选流1、备选流2

(7)场景7:基本流、备选流4

(8)场景8:基本流、备选流3、备选流4

12.9.3场景法设计测试用例的基本步骤

下面是场景法的基本设计步骤:

(1)根据说明,描述出程序的基本流及各项备选流

(2)根据基本流和各项备选流生成不同的场景

(3)对每一个场景生成相应的测试用例

(4)对生成的所有测试用例重新复审,去掉多余的测试用例,测试用例确定后,对每一个测试用例确定测试数据值

12.10逻辑覆盖法

逻辑覆盖是通过对程序逻辑结构的遍历实现程序的覆盖,可以分为以下7种覆盖:

语句覆盖SC (Statement Coverage)、

判定覆盖 DC (Decision coverage)、

条件覆盖CC (Condition Coverage)、

条件/判定覆盖 CDC(Condition/ Decision Coverage)、

多条件覆盖(条件组合覆盖) MCC(Multiple Condition Coverage)、

修正条件/判定覆盖 MCDC(Multiple Condition Decision Coverage)、

路径覆盖PC(Path Coverage)

为了方便说明,先看一下具体例子的源代码(C语言):

/*

 *  白盒测试逻辑覆盖测试范例

 *  作者:林雨辰(linyuchen2008@126.com)

 */

int logicExample(int x, int y)

{

    int magic=0;

    if(x>0 && y>0)

    {

        magic = x+y+10; // 语句块1 

    }

    else

    {

        magic = x+y-10; // 语句块2

    }

    

    if(magic < 0)

    {

        magic = 0;         // 语句块3

    }

    return magic;       // 语句块4

}

一般做白盒测试不会直接根据源代码,而是根据流程图来设计测试用例和编写测试代码,在没有设计文档时,要根据源代码画出流程图:

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130500834-1198808593.png

下面做好了上面的准备工作,接下来就开始讲解这几个逻辑覆盖标准:

12.10.1语句覆盖(SC)

12.10.1.1语句覆盖的概念

设计足够多的测试用例,使得被测试程序中的每条可执行语句至少被执行一次。在本例中,可执行语句是指语句块1到语句块4中的语句。

12.10.1.2语句覆盖的测试用例

{x=3, y=3}可以执行到语句块1和语句块4,所走的路径:a-b-e-f

{x=-3, y=0}可以执行到语句块2、语句块3和语句块4,所走的路径:a-c-d-f

这样,通过两个测试用例即达到了语句覆盖的标准,当然,测试用例(测试用例组)并不是唯一的。

12.10.1.3语句覆盖的充分性

假设第一个判断语句if(x>0 && y>0)中的“&&”被程序员错误地写成了“||”,即if(x>0 || y>0),使用上面设计出来的一组测试用例来进行测试,仍然可以达到100%的语句覆盖,所以语句覆盖无法发现上述的逻辑错误。

在六种逻辑覆盖标准中,语句覆盖标准是最弱的。

12.10.2判定覆盖(DC)

12.10.2.1判定覆盖的概念

设计足够多的测试用例,使得被测试程序中的每个判断的“真”、“假”分支至少被执行一次。在本例中共有两个判断if(x>0 && y>0)(记为P1)和if(magic < 0)(记为P2)。

12.10.2.2判定覆盖的测试用例

判定覆盖的测试用例如下表所示

表12-11  判定覆盖测试用例

数据

P1

P2

路径

{x=3, y=3}

T

F

a-b-e-f

{x=-3, y=0}

F   

T

a-c-d-f

两个判断的取真、假分支都已经被执行过,所以满足了判断覆盖的标准。

12.10.2.3判定覆盖的测试充分性

假设第一个判断语句if(x>0 && y>0)中的“&&”被程序员错误地写成了“||”,即if(x>0 || y>0),使用上面设计出来的一组测试用例来进行测试,仍然可以达到100%的判定覆盖,所以判定覆盖也无法发现上述的逻辑错误。

跟语句覆盖相比:由于可执行语句要不就在判定的真分支,要不就在假分支上,所以,只要满足了判定覆盖标准就一定满足语句覆盖标准,反之则不然。因此,判定覆盖比语句覆盖更强。

12.10.3条件覆盖(CC)

12.10.3.1条件覆盖的概念

设计足够多的测试用例,使得被测试程序中的每个判断语句中的每个逻辑条件的可能值至少被满足一次。

也可以描述成:设计足够多的测试用例,使得被测试程序中的每个逻辑条件的可能值至少被满足一次。

在本例中有两个判断if(x>0 && y>0)(记为P1)和if(magic < 0)(记为P2),共计三个条件x>0(记为C1)、y>0(记为C2)和magic<0(记为C3)。

12.10.3.2条件覆盖的测试用例

表12-12A  条件覆盖测试用例

数据   

C1

C2

C3

P1

P2

路径

{x=3, y=3}

T

T

T

T

F

a-b-e-f

{x=-3, y=0}

F

F

F

F

T

a-c-d-f

三个条件的各种可能取值都满足了一次,因此,达到了100%条件覆盖的标准。

12.10.3.3条件覆盖的测试充分性

上面的测试用例同时也到达了100%判定覆盖的标准,但并不能保证达到100%条件覆盖标准的测试用例(组)都能到达100%的判定覆盖标准,看下面的例子:

表12-12B  条件覆盖测试用例

数据   

C1

C2

C3

P1

P2

路径

{x=3, y=0}

T

F

T

F

F

a-c-e-f

{x=-3, y=5}

F

T

F

F

F

a-c-e-f

既然条件覆盖标准不能100%达到判定覆盖的标准,也就不一定能够达到100%的语句覆盖标准了。

12.10.4条件/判定覆盖(CDC)

12.10.4.1条件/判定覆盖的概念

设计足够多的测试用例,使得被测试程序中的每个判断本身的判定结果(真假)至少满足一次,同时,每个逻辑条件的可能值也至少被满足一次。即同时满足100%判定覆盖和100%条件覆盖的标准。

12.10.4.2条件/判定覆盖的测试用例

表12-13  条件/判定覆盖测试用例

数据   

C1

C2

C3

P1

P2

路径

{x=3, y=3}

T

T

T

T

F

a-b-e-f

{x=-3, y=0}

F

F

F

F

T

a-c-d-f

所有条件的可能取值都满足了一次,而且所有的判断本身的判定结果也都满足了一次。

12.10.4.3条件/判定覆盖的测试充分性

达到100%判定-条件覆盖标准一定能够达到100%条件覆盖、100%判定覆盖和100%语句覆盖。

12.10.5多条件覆盖(MCC)

12.10.5.1多条件覆盖的概念

设计足够多的测试用例,使得被测试程序中的每个判断的所有可能条件取值的组合至少被满足一次。

另外需要注意的是:

a、条件组合只针对同一个判断语句内存在多个条件的情况,让这些条件的取值进行笛卡尔乘积组合。

b、不同的判断语句内的条件取值之间无需组合。

c、对于单条件的判断语句,只需要满足自己的所有取值即可。

12.10.5.2多条件覆盖的测试用例

条件组合测试用例如下:

表12-14  条件组合覆盖测试用例

数据

C1

C2

C3

P1

P2

路径

{x=-3, y=0}

F

F

F

F

F

a-c-e-f

{x=-3, y=2}

F

T

F

F

F

a-c-e-f

{x=-3, y=0}

T

F

F

F

F

a-c-e-f

{x=3, y=3}

T

T

T

T

T

a-b-d-f

C1和C2处于同一判断语句中,它们的所有取值的组合都被满足了一次。

12.10.5.3多条件覆盖的测试充分性

当100%满足条件组合标准一定满足100%条件覆盖标准和100%判定覆盖标准。

但上面的例子中,只走了两条路径a-c-e-f和a-b-d-f,而本例的程序存在三条路径(a-b-d-f/a-c-d-f/a-c-e-f),还有一条路径是a-b-e-f,是不可能覆盖的路径。

12.10.6修正条件/判定覆盖(MCDC)

这个覆盖度量需要足够的测试用例来确定各个条件能够影响到包含的判定的结果。它要求满足两个条件:首先,每一个程序模块的入口和出口点都要考虑至少要被调用一次,每个程序的判定到所有可能的结果值要至少转换一次;

其次,程序的判定被分解为通过下面的逻辑操作符(and、or)连接的布尔条件,每个条件对于判定的结果值是独立的。

12.10.7路径覆盖(PC)

12.10.7.1路径覆盖的概念         设计足够多的测试用例,使得被测试程序中的每条路径至少被覆盖一次。

12.10.7.2路径覆盖的测试用例 表12-15  满足路径覆盖要求的一组测试用例,所有可能的路径都满足过一次。

数据

C1

C2

C3

P1

P2

路径

{x=3, y=5}

T

T

T

T

T

a-b-d-f

{x=0, y=2}

F

T

T

F

T

a-c-d-f

这条路径不可能

a-b-e-f

{x=-8, y=3}

F

T

F

F

F

a-c-e-f

12.10.7.3路径覆盖的测试充分性

由上表可见,100%满足路径覆盖,但并不一定能100%满足条件覆盖(C2只取到了真),但一定能100%满足判定覆盖标准(因为路径就是从判断的某条分支走的)

12.10.8各种覆盖逻辑之间的关系

各种覆盖逻辑之间的关系见下表:(其中,“Y”表示满足所在行头的覆盖一定满足所在列头的覆盖;“?”表示满足所在行头的覆盖不一定满足所在列头的覆盖)

表12-16  常见的逻辑覆盖之间的关系表

SC

DC

CC

CDC

MCC

MCDC

PC

SC

DC

Y

CC

?

?

CDC

Y

Y

Y

MCC

Y

Y

Y

Y

MCDC

Y

Y

Y

Y

?

PC

Y

Y

Y

Y

?

Y

 在外面很多的教程都认为这六种逻辑覆盖从弱到强的排列顺序是:

语句覆盖->判定覆盖->条件覆盖->判定-条件覆盖->条件组合覆盖->路径覆盖

 但经过上面的分析,它们之间的关系实际上可以用下图表示:

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130545974-1877853694.png

12.11基本路径覆盖法

12.11.1基本路径的设计步骤

基本路径测试法是在程序控制流图的基础上,通过分析控制构造的环路复杂性导出基本可执行路径集合,从而设计测试用例的方法。设计出的测试用例要保证在测试中程序的每个可执行语句至少执行一次。基本路径测试法包括以下4个方面:

(1)画出程序的流程图

程序流程控制图描述程序控制流的一种图示方法,可以使用流程图软件,如Microsoft和Visio来实现程序流程的描述。

(2)计算程序圈复杂性

通过对程序的控制流程图的分析和判断来计算模块复杂性度量。从程序的环路复杂性可导出程序基本路径集合中的独立路径条数,这是确定程序中每个可执行语句至少执行依次所必需的测试用例数目的上界。

(3)导出测试用例

通过程序流程图的基本路径来导出基本的程序路径的集合,这个过程和前面提到的逻辑覆盖法设计相类似。

(4)准备测试用例

确保基本路径集中的每一条路径的执行。

12.11.2程序流图的描述方法

工具方法:
图形矩阵:是在基本路径测试中起辅助作用的软件工具,利用它可以实现自动地确定一个基本路径集。
程序的控制流图:描述程序控制流的一种图示方法。
圆圈称为控制流图的一个结点,表示一个或多个无分支的语句或源程序语句

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130623209-2101444830.png

如何根据程序流程图画出控制流程图?

在将程序流程图简化成控制流图时,应注意:
(1)在选择或多分支结构中,分支的汇聚处应有一个汇聚结点。
(2)边和结点圈定的区域叫做区域,当对区域计数时,图形外的区域也应记为一个区域。

(3)如果判断中的条件表达式是由一个或多个逻辑运算符(OR, AND, NAND, NOR)连接的复合条件表达式,则需要改为一系列只有单条件的嵌套的判断。

独立路径:至少沿一条新的边移动的路径

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130639865-129713036.png

独立路径的计算:

独立路径:至少沿一条新的边移动的路径

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130657615-816940310.png

12.11.3基本路径法的实例

12.11.3.1第一步:画出控制流图

流程图用来描述程序控制结构。可将流程图映射到一个相应的流图(假设流程图的菱形决定框中不包含复合条件)。在流图中,每一个圆,称为流图的结点,代表一个或多个语句。一个处理方框序列和一个菱形决测框可被映射为一个结点,流图中的箭头,称为边或连接,代表控制流,类似于流程图中的箭头。一条边必须终止于一个结点,即使该结点并不代表任何语句(例如:if-else-then结构)。由边和结点限定的范围称为区域。计算区域时应包括图外部的范围。

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130720646-350836134.png

画出其程序流程图和对应的控制流图如下

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130740990-803889633.png

12.11.3.2第二步:计算圈复杂度

圈复杂度是一种为程序逻辑复杂性提供定量测度的软件度量,将该度量用于计算程序的基本的独立路径数目,为确保所有语句至少执行一次的测试数量的上界。独立路径必须包含一条在定义之前不曾用到的边。有以下三种方法计算圈复杂度:
(1)流图中区域的数量对应于环型的复杂性;
(2)给定流图G的圈复杂度V(G),定义为V(G)=E-N+2,E是流图中边的数量,N是流图中结点的数量
(3)给定流图G的圈复杂度V(G),定义为V(G)=P+1,P是流图G中判定结点的数量。

12.11.3.3第三步:导出测试用例

根据上面的计算方法,可得出四个独立的路径。

(一条独立路径是指,和其他的独立路径相比,至少引入一个新处理语句或一个新判断的程序通路。V(G)值正好等于该程序的独立路径的条数。)

路径1:4-14

路径2:4-6-7-14

路径3:4-6-8-10-13-4-14

路径4:4-6-8-11-13-4-14

根据上面的独立路径,去设计输入数据,使程序分别执行到上面四条路径。

12.11.3.4第四步:准备测试用例

为了确保基本路径集中的每一条路径的执行,根据判断结点给出的条件,选择适当的数据以保证某一条路径可以被测试到,满足上面例子基本路径集的测试用例是:

导出的测试用例如下:

https://images2015.cnblogs.com/blog/1054782/201611/1054782-20161128130800412-1949131029.png

12.11.4路径覆盖法要点

熟悉测试理论的人都知道,路径覆盖是白盒测试中一种很重要的方法,广泛应用于单元测试。采用路径分析的方法设计测试用例有两点好处:一是降低了测试用例设计的难度,;二是在测试时间较紧的情况下,可以有的放矢的选择测试用例,而不用完全根据经验来取舍。下面就具体的介绍一下如何用路径分析的方法编写测试用例。

(1)首先是将系统运行过程中所涉及到的各种流程图表化。

(2)找出了所有的路径,下面的工作就是给每条路径设定优先级。
(3)为每条路径设定好优先级后,接下来工作就是为每条路径选取测试数据,构造测试用例。
(4)对于测试人员而言,测试用例的设计是一件非常困难的工作,而同时测试用例的设计好坏又直接关系到整个系统的设计质量。本文介绍了一种更理论化的设计方法来尽量简化这种工作,将一般应用于单元测试的路径分析方法推广到集成测试、系统测试等后续测试过程中,希望能给大家一点启示。

代码编程
赞赏

相关文章

她是个好女孩
初一有感…
爱你……不愿放弃
爱自己
等你
对不起,我爱你