软件测试的艺术(原书第3版)
上QQ阅读APP看书,第一时间看更新

4.2.1 等价划分

本书第2章将一个好的测试用例描述为具有相当高的可能性发现某个错误来,此外还讨论了对程序的穷举输入测试是无法实现的。因此,当测试某个程序时,我们就被限制在从所有可能的输入中努力找出某个小的子集。理所当然,我们要找的子集必须是正确的,并且是可能发现最多错误的子集。

确定这个子集的一种方法,就是要意识到一个精心挑选的测试用例还应具备另外两个特性:

1.严格控制测试用例的增加,减少为达到“合理测试”的某些既定目标而必须设计的其他测试用例的数量。

2.它覆盖了大部分其他可能的测试用例。也就是说,它会告诉我们,使用或不使用这个特定的输入集合,哪些错误会被发现,哪些会被遗漏掉。

虽然这两个特性看起来很相似,但描述的却是截然不同的两种思想。第一个特性意味着,每个测试用例都必须体现尽可能多的不同的输入情况,以使最大限度地减少测试所需的全部用例的数量。而第二个特性意味着应该尽量将程序输入范围进行划分,将其划分为有限数量的等价类,这样就可以合理地假设(但是,显然不能绝对肯定)测试每个等价类的代表性数据等同于测试该类的其他任何数据。也就是说,如果等价类的某个测试用例发现了某个错误,该等价类的其他用例也应该能发现同样的错误。相反,如果测试用例没能发现错误,那么我们可以预计,该等价类中的其他测试用例不会出现在其他等价类中,因为等价类是相互交迭的。

这两种思想形成了称为等价划分的黑盒测试方法。第二种思想可以用来设计一个“令人感兴趣的”输入条件集合以供测试,而第一个思想可以随后用来设计涵盖这些状态的一个最小测试用例集。

本书第1章中三角形程序的一个等价类的例子是集合“三个值相等、都大于0的整型数据”。将此作为一个等价类后,我们就可以说,如果对该集合中某个元素所进行的测试没有发现错误的话,那么对该集合中其他元素所进行的测试也不大可能会发现错误。换言之,我们的测试时间最好花在其他地方(其他的等价类)。

使用等价划分方法设计测试用例主要有两个步骤:(1)确定等价类;(2)生成测试用例。

4.2.1.1 确定等价类

确定等价类是选取每一个输入条件(通常是规格说明中的一个句子或短语)并将其划分为两个或更多的组。可以使用图4-3中的表格来进行划分。注意,我们确定了两类等价类:有效等价类代表对程序的有效输入,而无效等价类代表的则是其他任何可能的输入条件(即不正确的输入值)。这样,我们遵循了本书第2章阐述的测试原则,即要注意无效和未预料到的输入情况。

figure_0054_0029
图 4-3 等价类列举表

在给定了输入或外部条件之后,确定等价类大体上是一个启发式的过程。下面给出了一些指导原则:

1.如果输入条件规定了一个取值范围(例如,“数量可以是从1到999”),那么就应确定出一个有效等价类(1<数量<999),以及两个无效等价类(数量<1,数量>999)。

2.如果输入条件规定了取值的个数(例如,“汽车可登记一至六名车主”),那么就应确定出一个有效等价类和两个无效等价类(没有车主,或车主多于六个)。

3.如果输入条件规定了一个输入值的集合,而且有理由认为程序会对每个值进行不同处理(例如,“交通工具的类型必须是公共汽车、卡车、出租车、火车或摩托车”),那么就应为每个输入值确定一个有效等价类和一个无效等价类(例如,“拖车”)。

4.如果存在输入条件规定了“必须是”的情况,例如“标识符的第一个字符必须是字母”,那么就应确定一个有效等价类(首字符是字母)和一个无效等价类(首字符不是字母)。

如果有任何理由可以认为程序并未等同地处理等价类中的元素,那么应该将这个等价类再划分为小一些的等价类。稍后我们将给出这个过程的例子。

4.2.1.2 生成测试用例

第二步是使用等价类来生成测试用例,其过程如下:

1.为每个等价类设置一个不同的编号。

2.编写新的测试用例,尽可能多地覆盖那些尚未被涵盖的有效等价类,直到所有的有效等价类都被测试用例所覆盖(包含进去)。

3.编写新的用例,覆盖一个且仅一个尚未被涵盖的无效等价类,直到所有的无效等价类都被测试用例所覆盖。

用单个测试用例覆盖无效等价类,是因为某些特定的输入错误检查可能会屏蔽或取代其他输入错误检查。举例来说,如果规格说明规定了“请输入书籍类型(硬皮、软皮或活页)及数量(1~999)”,代表两个错误输入(书籍类型错误,数量错误)的测试用例“XYZ 0”,很可能不会执行对数量的检查,因为程序也许会提示“XYZ是未知的书籍类型”,就不检查输入的其余部分了。