工程师借助先行者的想法来为后知后觉者建造产品。
从本质上来说,所有的测试都是从待测软件的输入空间中选择元素。而输入空间划分技术的特点是根据程序输入的逻辑关系来直接划分输入空间。
我们将输入域定义为输入参数可能拥有的全部测试值。
根据待分析的软件工件的种类,输入参数可以是方法参数和非局部变量(在单元测试中)、代表程序当前状态的对象(当测试类时或在集成测试中)或是用户对程序的输入(在系统测试中)。
划分覆盖的基本思想中,假设覆盖任一区块的测试用例和覆盖其他区块的测试用例一样有效。有时我们会同时考虑若干个划分,如果处理不当,可能会导致测试用例的的组合爆炸问题。
应用输入空间划分的一个通用方法是分别考虑每个参数的值域,将每个域中包含的值划分到不同的区块中,然后为每个参数组合区块。有时我们可以完全独立地考虑每个参数,有时需要根据程序中的语义将某些参数联合起来考虑。这个过程称为输入域建模。
测试者根据特征定义一个划分,一个划分必须满足两个属性
1、这个划分必须覆盖整个值域(完整性)
2、区块之间不能有重叠(互斥性)
6.1 输入域建模
输入域建模的第一步是识别可以测试的功能。
输入域建模的第二步是在已有的可测功能中进一步识别所有可以影响软件行为的参数。
输入域建模的第三步就是建模,这是关键且具有创造性的一步。
输入域模型用一种抽象的方式表达了待测系统的输入空间。测试工程师根据输入特征来描述输入域的结构,为每个特征创建一个划分。划分就是若干个区块的集合,每个区块都包含一组值。对于每个具体的特征,每个区块中所有的值都是等价的。
一个测试输入由一行测试值组成,每个值对应一个参数。根据定义,测试输入从每个特征中只使用一个区块。
建模方法又分为两种:
基于接口的和基于功能的输入域建模。
6.1.1 基于接口的输入域建模
这种方法独立分析每个参数。这种方法机械式地遵循原则,但是最后产生地测试用例的质量通常还是非常不错的。
优点:容易辨识特征
缺点:从接口生成的输入域模型并不能包含测试工程师已知的所有信息,可能会不全面。还有某些部分可能依赖于接口参数取值的特定组合。
6.1.2 基于功能的输入域建模
基于功能的方法的思想是识别与待测系统所设计的行为和功能相对应的特征,而不是使用实际的接口来提取特征。
优点:需求在软件实现之前就已经存在,就是说我们可以在软件开发的早期就开始输入域建模和测试用例生成。
缺点:识别特征和测试值可能会变得很复杂,如果待测系统变得很复杂,或是规范没有形式化而且不完整。
6.1.3 设计特征
在基于接口的方法中设计特征是相对简单的,只需要从参数到特征的一个按部就班的转换。而设计基于功能的IDM则更具有挑战性。
前置条件是得到基于功能的特征的绝好来源。有些异常行为可能已经被明确列出或是编码在软件中。前置条件可以明确地将已定义的和未定义的行为分离开来。
后置条件有时设计特征的一个不错的来源,对于triang()方法来说,识别不同种类三角形的特征就是基于该方法的后置条件。
另一可行的思路是检查缺失的因素,就是那些可能影响程序执行但是还未列入相关IDM参数的因素。
有的特征只有极少的区块,这些特征更有可能满足互斥性和完整性属性。基于这个原因,通常设计更多带有很少区块的特征是一种更好的选择。通常情况下,推荐测试工程师使用规范或其他的文档而非程序代码来开发特征,这里思路是测试者应该使用问题的专业领域知识而不是代码实现来实施输入空间划分。
6.1.4 选择区块和测试值
一些将特征划分为区块的通用策略。对于给定的任意特征,都可以应用其中的一到两个策略。
有效值和无效值: 每个划分都必须包含所有的值,不管这些值是有效还是无效的。(这就是简单的重复完整性的定义)
子划分: 一个区块的有效值经常可以被切分为更细的子划分,每个子划分可以执行功能的不同部分。
边界: 使用边界值或靠近边界的值通常可以引起问题。这是压力测试的一种。
正常使用(大众路径): 如果软件的操作集中在正常的使用上,那么失败率会依赖于不属于边界条件的测试值。
枚举类型: 划分的区块可以是离散的枚举类型值的集合,有时候这样的划分是合理的选择,三角形的例子就使用了这种方法。
平衡: 从成本的角度来说,在那些很少区块的特征中增加一些区块的花销是很低的,甚至是零。测试用例的数目有时只依赖于具有最大区块数目的那些特征。
遗漏的区块: 检查一个特征中所有区块的联合是否完全覆盖了该特征的输入空间。
重叠的区块: 检查是否有测试值同时属于两个或两个以上的区块。
6.2 组合策略准则
我们应该如何同时考虑多个划分?
完全组合覆盖: 必须使用来自所有特征区块的所有组合。
单一选择覆盖: 每个特征的每个区块中的一个测试值必须要在至少一个测试用例中出现。
结对覆盖: 每个特征的每个区块中的一个测试值必须要与其他特征的每个区块中的测试值进行组合。
多项组合覆盖: 所有由t个特征构成的组合的每个区块中的测试值都必须要进行组合。
基本选择覆盖: 每个特征都选取一个区块作为基本选择,使用每个特征的基本选择构成一个基本测试用例。剩余的测试用例保持基本测试用例中除了一个基本选择常量之外的所有值,然后使用其他特征中的每个非基本选择来代替那个基本选择。
基本选择可以是区块中最简单的、最小的、以某种顺序的第一个或是最终用户最可能使用的那一个。将多于一个的无效值组合起来通常是无用的,这是因为当软件识别一个无效值时,其他无效值的副作用通常会被屏蔽。选择哪个区块作为基本选择在测试设计中变成了关键的一步,因为它可以极大地影响所产生地测试测试用例。
多项基本选择覆盖: 每个特征选取至少一个或多个区块作为基本选择,使用每个特征的基本选择构成一个基本测试用例。剩余的测试用例保持每个基本测试用例中除了一个基本选择常量之外的所有值,然后使用其他特征中的每个非基本选择来代替那个基本选择。
6.3 检查特征之间的约束关系
输入空间划分的一个微妙之处在于某些区块的组合是不可行的,我们必须在IDM中记录这些组合。一般来说,约束表示了来自不同特征的区块之间的关系。
IDM有两大类约束,第一类约束要求来自一个特征的一个区块不能和来自另一个特征放入某个区块组合;第二类则正好相反,来自一个特征的一个区块必须和来自另一个特征的某个区块相结合。