一,概述
基于规格说明的测试的依据为软件需求规格说明,以及模型、用户需求等,把程序看作一个黑盒子,不考虑程序内部结构和内部特性,在程序接口进行测试,检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能有效接收输入数据而产生正确的输出信息。
运用基于规格说明的测试技术,可以导出满足以下标准的测试用例集:
①所设计的测试用例能够减少达到合理测试所需的附加测试用例数。
②所设计的测试用例能够告知某些类型错误的存在或不存在,而不是仅仅与特定测试相关的错误。
二,等价类划分法
定义:把程序的输入域划分成若干部分(子集),然后从每个部分中选取少数代表性的数据作为测试用例。每一类的代表性数据在测试中的作用可以等价于这一类中的其他所有值,这就是“等价类”这个名字的由来。
如果某一类中的一个数据发现了错误,这一等价类中的其他数据也能发现同样的错误;反之,如果某一类中的一个数据没有发现错误,则这一类中的其他数据也不会查出错误(除非等价类中的某些数据同时属于另一等价类,因为几个等价类之间是可能相交的)。
等价类划分有两种不同的情况:有效等价类和无效等价类。
有效等价类指的是对于程序的规格说明来说是合理的、有意义的输入数据构成的集合。利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能。
无效等价类与有效等价类的定义恰巧相反,是那些对于程序的规格说明来说是不合理的或无意义的输入数据所构成的集合。
常见的划分等价类的方式包括按区间划分、按数值划分、按数值集合划分、按限制条件或规划划分、按处理方式划分等。
下面给出6条划分等价类的原则:
①在输入条件规定了取值范围或值的个数的情况下,可以确立一个有效等价类和两个无效等价类。(例如:程序输入条件为1-10)
②在输入条件规定了输入值的集合或者规定了“必须如何”的条件的情况下,可以确立一个有效等价类和一个无效等价类。(例如:输入条件规定x取值必须是偶数)
③在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类。
④在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和一个无效等价类。(例如:销售奖金对第1,2,3名分别奖励)
⑤在规定了输入数据必须遵守的规则的情况下,可确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。(例如:输入规定必须为整数)
⑥在确知已划分的等价类中,各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步划分为更小的等价类。
建立等价类:一个等价类表的典型例子如表所示。一个软件中要求用户输入以年月表示的日期,假定日期的输入范围限定在2000 年1 月至2100 年12月之间,并且规定日期由6 位数字字符组成,前4 位表示年,后2 位表示月,那么对应的“日期输入格式检查”这一功能的等价类表可以设计如下。

确定测试用例步骤:
①为每个等价类规定一个唯一的编号。
②设计一个新的测试用例,使其尽可能多地覆盖尚未覆盖的有效等价类。重复这一步,最后使得所有有效等价类均被测试用例所覆盖。
③设计一个新的测试用例,使其只覆盖一个无效等价类。重复这一步使所有无效等价类均被覆盖。
设计的有效类测试用例:

设计的无效类测试用例:

三,分类树法
分类树是另一种对程序的输入域划分子集的方法。它将输入域分割成若干个独立的分类,每个分类再根据一定的准则再次划分分类和子类,直到将整个输入域分割成一些不可再分的子类的组合为止。每一次划分都会生成若干个独立而不重叠的类或子类,同时还应保证分类集的完整性,即所有输入域都被识别且被包括在了某个分类中。
旅行选项案例说明

分类树划分完毕之后,可以通过结合表的方式将各个叶子结点的内容结合而成测试用例。分类树的划分过程和等价类划分有点类似,但两者的区别在于,分类树方法中所划分出的类是完全不相交的,而在等价类划分中,它们某些时候也可能会重叠。
四,边界值法
边界值测试是源于人们长期以来的测试工作经验所提出的一个关键假设:错误更容易发生在输入域的边界或者说极值附近,而非输入域的中间部分。
边界值的选择可以分为二值边界测试和三值边界测试。对于二值边界测试,应为每个边界选择两个输入,这些输入对应于边界上的值和等价划分边界外的增量距离;对于三值边界测试,应为每个边界选择三个输入,这些输入对应于边界上的值和等价划分边界的每一侧的增量距离。增量距离应定义为对应的数据类型的最小有效值。
二值基本边界值分析:如果有一个n变量的软件输入域,使其中一个变量取略小于最小值、最小值、正常值、最大值、略大于最大值这样五种选择,其余的所有变量取正常值。如此对每个变量都重复进行之后,该n 变量软件输入域的边界值分析会产生4n+ 1个测试用例。
三值基本边界值分析:如果有一个n 变量的软件输入域,使每个变量取略小于最小值、最小值、略大于最小值、正常值、略小于最大值、最大值、略大于最大值这样七种选择,其余的所有变量取正常值。如此对每个变量都重复进行之后,该n 变量软件输入域的边界值分析会产生6n+ 1个测试用例。
五,语法测试
语法模型表示为多个规则, 其中每个规则根据语法中的元素“序列”、元素“迭代”或元素“之间的选择” 来定义输入参数的形式。
语法测试中的测试条件应为输入的全部或部分语法模型。
在语法测试中,应基于两个目标来设计测试用例:
①正面测试,设计的测试用例应以各种方式覆盖有效语法;
②负面测试,设计的测试用例应故意违反规则语法。
正面测试应是已定义语法的“选项”,而负面测试应是已定义语法的“变异”。
在使用语法测试来设计用例时,应考虑如下的指导原则:
①每当语法强制选择时,就为该选择的每个备选方案导出一个“选项”。
例如:对于输入变量“颜色=蓝色|红色|绿色”(“|”表示“或”布尔运算符),则导出三个选项“蓝色”“红色”“绿色”。
②每当语法强制执行迭代时,为此迭代导出至少两个“选项”,一个包含了最小重复次数,另一个则大于最小重复次数。
例如:输入变量“字母= [A-Z丨a-z] +”(“+”表示“一个或多个”),则导出两个选项“一个字母”和“多个字母”。
③每当迭代被要求具有最大重复次数时,为此迭代导出至少两个“选项”,一个具有最大重复次数,另一个则超过最大重复次数。
例如:输入变量“字母= [A-Z丨a-z]¹⁰⁰”(“ 100 ” 表示一个字母最多选择100 次),至少生成两个选项“ 100 个字母”和“多于100 个字母”。
④对于任何输入,可以对定义的语法改变以导出无效输入(“变异”)。
例如:输入变量“颜色=蓝色|红色|绿色”,一个变异可能引入一个无效的变量值,选择颜色“黄色”,“黄色”没有在输入变量列表中出现。
六,组合测试
组合测试的目的,就是为组合爆炸情况提供一种相对合理的解决方案,在保证错误检出率的前提下采用较少的测试用例,它将被测软件抽象成一个受到多个参数影响的系统,并通过被测软件的参数和参数可取的值,按照一定的组合策略来规划测试。当多参数(每个参数都有大量离散值)必须相互作用的情况下,这种技术可以显著减少所需的测试用例数量,而不会影响功能覆盖率。
组合测试的输入数据要求:参与组合的参数的取值范围必须是可离散的。例如操作系统和浏览器的版本(至今已发布的版本数量是确定的),工作日期是星期几(只能取7 个特定值)等。
对于取值范围连续的参数(例如实数类型)或者存在过多的取值,有必要先使用其他测试设计技术,如等价类划分、分类树、边界值等,将一个很大的取值范围减少为一个可控的子集。
组合测试的实施步骤:
①根据测试目标,识别出所需测试的软件功能,以及影响被测软件功能的参数。
②依据步骤①的结果,识别每个参数的取值范围。取值范围应为有限个离散取值。如果某参数的取值范围不符合要求,则采用其他测试技术对其进行离散化处理。
③依据步骤①的结果,识别出参数间的约束。分析各参数间交互作用的强度,设定指导测试用例设计的组合强度。
④根据步骤③中设定的组合强度,采用对应组合测试方法,生成与组合强度相符的测试覆盖项。
⑤依据步骤④中的测试覆盖项生成测试用例,直到每个测试覆盖项都包含在至少一个测试用例中。
常见的组合强度包括单一选择、基本选择、成对组合、全组合和K 强度组合等。
①单一选择:被测软件中的所有参数取值范围的任意可能取值至少被一个测试用例覆盖。
②基本选择:被测软件中,对于任意一个参数的两个取值,存在两个测试用例覆盖这两个取值,且其他参数的取值相同。
③成对组合:被测软件中任意两个参数,它们取值范围的任意一对有效取值至少被一个测试用例所覆盖。
④全组合:被测软件中所有参数取值范围的任意有效取值的组合至少被一个测试用例所覆盖。
⑤K 强度组合:在组合强度要求为K 的组合中(简称为K 强度),任意K 个参数取值范围的任意有效值的组合至少被一个测试用例覆盖。
当K= 1,K 强度组合就是单一选择;当K=2,K 强度组合就等同于成对组合; 而当K 等于所有参数数量时, K 强度组合等同于全组合。
七,判定表测试
判定表展示出输入条件与输出结果的对应关系。判定表测试以判定表的形式使用了测试项条件(原因)和动作(结果)之间的逻辑关系(判定规则)模型。
判定表通常由四个部分组成:
① 条件桩(condition stub):列出了问题的所有条件。通常认为列出的条件的次序无关紧要。
② 动作桩(action stub):列出了问题规定可能采取的操作。这些操作的排列顺序没有约束。
③ 条件项(condition entry):列出针对它所列条件的取值,在所有可能情况下的真假值。
④ 动作项(action entry):列出在条件项的各种取值情况下应该采取的动作。
规则:任何一个条件组合的特定取值及其相应要执行的操作。在判定表中贯穿条件项和动作项的一列就是一条规则。显然,判定表中列出多少组条件取值,也就有多少条规则,条件项和动作项就有多少列。
建立判定表的步骤:
① 确定规则的个数。假如有n个条件,每个条件有两个取值(0, 1),则有2^n种规则。
② 列出所有的条件桩和动作桩。
③ 填入条件项。
④ 填入动作项。制定初始判定表。
⑤ 简化。合并相似规则或者相同动作。
支票借记功能示例:
• 输入:借记金额、账户类型和当前余额;输出:新的余额和操作代码。
• 账户类型:邮政(“p”)类型或柜台(“c”)类型。
• 操作代码:“D&L”“D”“S&L”“L”,分别对应“处理借记并发送信件”“只处理借记”“冻结账户和发送信件”“只发送信件”。
• 功能描述:如果账户中有足够的金额或者新的余额在授权透支的范围内,则处理借记。如果新的余额超过了授权透支的范围,则不处理借记,如果是一个邮政账户则进行冻结。邮政账户的所有交易都会发送信件,非邮政账户如果有足够的资金也会发送信件(即账户将不再是信贷)。
• 条件桩(C):
C1:账户中有足够金额;
C2:新的透支余额在授权范围内;
C3:账户是邮政类型。
• 动作桩(A):
A1:处理借记;
A2:冻结账户;
A3:发送信件。

判定表补充说明
• 在本判定表中,每一列是一个判定规则。实际操作中也可以把整个判定表转置过来,用行的形式来显示判定规则。
• 条件桩中T表示条件为真,F表示条件为假;动作桩中T表示动作要执行,F表示动作不执行;*表示条件组合是无效的。本例一共可以导出6个测试用例。
适合使用判定表设计测试用例的条件
① 规格说明以判定表的形式给出,或很容易转换成判定表。
② 条件的排列顺序不影响执行哪些操作。
③ 规则的排列顺序不影响执行哪些操作。
④ 当某一规则的条件已经满足,并确定要执行的操作后,不必检验别的规则。
⑤ 如果某一规则要执行多个操作,这些操作的执行顺序无关紧要。
八,因果图法
因果图是一种简化了的逻辑图,能直观地表明输入条件和输出动作之间的因果关系。因果图可帮助测试人员把注意力集中到与软件功能有关的输入组合上,使用因果图来辅助设计测试用例,非常适合描述多种输入条件的组合。根据输入条件的组合、约束关系和输出条件的因果关系,分析输入条件的各种组合情况,从而设计测试用例。

为了表示原因与原因之间、结果与结果之间可能存在的约束条件,在因果图中可以附加一些表示约束条件的符号。

利用因果图导出测试用例的步骤
① 分析程序规格说明的描述中,哪些是原因,哪些是结果。原因常常是输入条件或是输入条件的等价类,而结果是输出条件。
② 分析程序规格说明的描述中语义的内容,并将其表示成连接各个原因与各个结果的“因果图”。
③ 标明约束条件。由于语法或环境的限制,有些原因和结果的组合情况是不可能出现的。为表明这些特定的情况,在因果图上使用若干个标准的符号标明约束条件。
④ 把因果图转换成判定表。
⑤ 为判定表中每一列表示的情况设计测试用例。
九,状态转移测试
状态转移测试是把被测软件的若干状态以及状态之间的转换条件和转换路径抽象出来,从覆盖所有状态转移路径的角度去设计测试用例,关注状态的转移是否正确。
有限状态机是一种用来进行对象行为建模的工具,主要用于描述对象在其生存周期内所经历的状态序列,以及如何响应来自外界的各种事件进行状态转移。
状态转移测试的步骤:
① 画出状态迁移图;
② 列出状态-事件表;
③ 画出状态转换树,并从状态转换树推导出测试路径;
④ 根据测试路径编写测试用例。
状态转移测试的覆盖率要求:
• 状态覆盖:能使状态模型中所有的状态都被“访问”到。
• 单步转移(0-switch):应能覆盖状态模型中的有效单步转移。
• 全转移:应能覆盖状态模型中的有效转移和无效转移(从状态模型中未指定有效转移的事件启动的状态转移)。
• 多步转移(N-switch):应能覆盖状态模型中N+1步转移的有效序列。
• 其中,“2步转移”覆盖是“多步转移”覆盖的一种特殊情况,要求实现成对的转移。
十,场景测试
• 现在的软件几乎都是用事件触发来控制流程的,事件触发时的情景便形成了场景,而同一事件不同的触发顺序和处理结果就形成了事件流。
• 场景测试使用被测软件与用户或其他系统之间的交互序列模型来测试被测软件的使用流程。测试条件是需要在测试中覆盖的基本场景和可选场景(即用户和系统交互的事件流序列组成一个场景)。
• 场景测试应该包括以下场景:
◦ “基本”场景,是被测软件的预期典型动作序列,或无典型动作序列时所采取的一个任意选择;
◦ “可选”场景,表示被测软件可选择的(非基本)场景。备选的场景包括非正常的使用、极端或者压力条件和异常等。
ATM系统示例
系统要求
允许有银行账户的客户通过ATM从他们的账户取款。取款要求用户必须有一个激活的账户、一张有效的卡和匹配的密码以及一台可工作的ATM。当取款完成后,账户余额扣除取款金额,打印取款回执条,ATM可用于为下一位用户服务。
场景定义
• 基本场景:成功从账户取款。
• 可选场景(不支持取款的情况):
1. 银行卡不能被ATM识别,被拒绝;
2. 用户输入密码错误不多于2次;
3. 用户输入密码错误3次,ATM吞卡;
4. 用户选择存款或者转账,不选择取款;
5. 用户选择了错误账户,此账户在插入的卡中不存在;
6. 用户输入的取款金额是无效的;
7. ATM中现金不足;
8. 用户输入不符合面额的取款金额;
9. 用户输入的取款金额超过了每日最大取款金额;
10. 用户银行账户中的金额不足。

十一,随机测试
• 随机测试的目的是在选定的输入分布模型内生成被测软件的输入参数,形成一个测试集。这种测试技术不需要对被测软件的输入域进行划分,仅要求输入值是从输入域中随机选择的。
• 随机测试一般用在测试用例自动化生成和执行的过程中。常见的被测软件输入分布模型的定义如正态分布、均匀分布、运行剖面等。
• 按照预先定义好的输入分布模型,计算机随机选择输入值并执行,反复迭代这一过程直到满足事先定义好的停止条件为止。
• 随机测试可以手动测试或自动化测试。完全自动化随机测试不需要人工干预,是最有效率的。但是,为了达到完全自动化,必须满足:
◦ 自动生成随机测试的输入值;
◦ 从测试依据中自动生成预期结果;
◦ 自动按测试依据核对测试结果。
十二,测试设计方法选择策略
① 首先采用分类树或等价类对函数的输入域进行划分,将无限测试变成有限测试,这是减少工作量和提高测试效率最有效的方法。
② 在任何情况下都必须使用边界值分析方法。经验表明,用这种方法设计出的测试用例发现程序错误的能力最强。
③ 对于参数配置类的软件,要用组合测试技术选择较少的组合方式达到最佳效果。
④ 如果程序的功能说明中含有输入条件的组合情况,则一开始就可选用因果图法绘制判定表,然后采用判定表法继续进行测试。
⑤ 对于业务流清晰的系统,场景测试法可以贯穿整个测试案例过程,综合考察软件的主要业务流程、功能和错误处理能力。
⑥ 状态转移测试对于明确存在不同状态转移的软件设计测试用例的效果非常好,我们可以通过不同状态间的转移条件的有效性设计不同的测试数据。
⑦ 对照程序逻辑,检查已设计出的测试用例的逻辑覆盖程度。如果没有达到要求的覆盖标准,应当再补充足够的测试用例。
⑧ 如测试用例自动生成和使用中可以结合被测软件实际,考虑选用分类树、状态转移测试、随机测试等多种方式。
⑨ 对于形式化方式定义的规格说明,语法测试是一种比较适合的方式。
十三,测试用例的编写
编写测试用例,在整个软件测试过程中是属于动态测试过程中的测试设计和实现过程的工作。
测试用例编写步骤:
① 分析被测软件的相关测试依据,将待测的特征组合成特征集,记录在测试设计规格说明中;
② 根据测试计划中规定的测试完成准则,确定每个特征的测试条件,并记录在测试设计规格说明中;
③ 根据测试条件,导出测试覆盖项,记录在测试用例规格说明中;
④ 根据测试覆盖项,导出测试用例,并记录在测试用例规格说明中;
⑤ 根据执行的约束将测试用例汇集到一个或多个测试集中,记录在测试规程规格说明中;
⑥ 根据前置条件和后置条件,以及其他测试要求所描述的依赖性,对测试集中的各测试用例进行排序,导出测试规程,并将其记录在测试规程规格说明中。
该过程的最终工作产品包括测试设计规格说明、测试用例规格说明和测试规程规格说明三个文档。
测试设计规格说明:
• 测试设计规格说明是测试设计和实现过程的第一个工作产品,它确定了要测试的特征,并从每个特征的测试依据导出测试条件,作为定义测试用例和要执行的测试规程的第一步。
• 特征集是测试项需被测试的特征的逻辑分组,一般地,特征集可能直接对应测试项的体系结构,也可能为了更有效率的测试,与体系结构不同。特征集也可能是由一系列特征组成的业务流程。
• 特征集应包括如下内容:唯一标识符(供追溯和区分)、目标、测试优先级、具体策略和可追溯性。例如用于说明被测软件功能的文字等。
• 在总结完特征集后,需要将对应的测试依据指定的项或事件梳理成测试条件。测试条件可能是一个需求的简单引用或一个设计描述,也可以是需求或一组需求的重新措辞。
• 测试条件应包括如下内容:唯一标识符、测试条件描述、测试优先级和可追溯性。例如:等价类、边界、语法模型等。
测试用例规格说明:
• 测试用例规格说明:该文档标识了测试覆盖项,以及从一个或多个特征集的测试依据导出的相应测试用例。
• 测试覆盖项指的是使用测试设计技术从测试条件中导出的,预计未来的测试用例将覆盖的内容。
• 完整的测试覆盖项应包括以下内容:唯一标识符(供追溯和区分)、测试覆盖项描述、测试优先级和可追溯性,每个测试覆盖项都能追溯到其所属的测试条件、特征集或其引用的测试依据。例如:等价类的划分、分类树的组合分类、不同边界值法到处的用例等。
• 针对每个测试覆盖项再进一步导出测试用例。
• 一个导出的完整的测试用例应包括以下内容:唯一标识符(供追溯和区分)、测试目标、测试优先级、可追溯性、测试的前置条件、输入、预期结果和评价判定结果的准则,在执行完测试之后再增加对应的实测结果和结果判定。每个测试用例都能追溯到对应的一个或多个测试覆盖项。
测试规程规格说明:
• 测试规程规格说明:就是用于解决测试用例从“设计”到“执行”这一问题的文档。该文档按照执行顺序描述了所选测试集中的测试用例,以及设置初始前置条件和任何执行结束后活动所需的任何相关操作。
• 测试集通常会反映特征集,但是它们也可包含许多特征集的测试用例。
• 选择哪些测试用例进入一个测试集,可以根据识别的风险、测试依据、执行约束、复测和/或回归测试等来选择。
• 一个测试集的描述应包括以下内容:唯一标识符(供追溯和区分)、测试目标、测试优先级、测试集内容(可追溯性)。
• 测试规程指定的是对应测试集中的测试用例如何按照前置条件、后置条件以及其他测试需求所描述的依赖关系执行的顺序和操作。
• 一个测试规程应包括以下内容:唯一标识符(供追溯和区分)、启动操作、待执行的测试用例、与其他规程的关系、如何停止及结束测试等。
夜雨聆风