黑盒测试技术
黑盒测试常常也被称为功能性测试,是相对于白盒的基于程序设计的结构测试来说。主要是用来测试系统功能是否正确实现,通常是要基于软件需求规格说明来进行,所以也被称为requirement-based testing或者specification-based testing。黑盒也意味着测试人员并不关心软件的具体实现代码的正确与否。大多数情况下(现实情况我想也大概如此),程序员会进行白盒测试,而测试人员则会进行黑盒测试。
黑盒测试方法经历多年的发展,已经有很多种,我想不下十来种了。这里主要还是介绍传统也是最有效的方法,从这个侧面给人启发,简单才是最好的方法。
一、等价类 Equivalence Partition
这种方法应该是应用最多的一种方法了,即使你没有学过,如果你测试过某个软件,那你肯定会在使用等价类这种方法,没有人会用穷举所有的输入组合去验证一个功能是否正确,当然也有例外,穷举却是破译密码的一个基本方法。这里说到了输入(input),我们总是不自觉地在做出很多推断,将人分为三六九等,会假定某人和你是同一类人,所以某人对待某件事情的想法会与本人一致,不过在很多时候这种想法却是重大错误的根源,好比GF就最好区别对待。不过将输入分成若干个等价类,确实我们执行黑盒测试的一个省时省事的好方法。
每个系统都可以组织不同的大量的测试数据,如果要进行完整的测试,测试工作将会是不可能完成的任务,所以根据不同的系统行为(这里的系统行为并不是说结果要完全一致,好像我们每张订单都有唯一的订单编号,但是我们不会认为不同编号的订单设计不同系统行为)把整个输入域分解成为几个有限的输入域,每个输入域代表了不同的系统行为,而测试的时候我们只需要在不同的输入域之中随意选取测试数据进行测试就可以达到这种系统行为的测试覆盖,也将会大大减轻我们的测试工作。
再用订单来举个例子:创建一张销售订单,销售订单分成出口,进口两种,两种订单会有不同的系统行为,比如输入了是进口的单系统将提示进口单,如果是出口系统将提示出口单。
我们来分析一下这个需求的输入,订单的输入可想而知包括了许多订单的相关资料,好像客户,产品,数量等等,但是从规则来看这些资料并不会影响系统的行为,而订单类型是出口还是入口才决定了不同系统行为,所以我们可以把输入域分成两个输入域,出口单和进口单
{订单类型=出口,其他资料=any}
{订单类型=进口,其他资料=any}
我们测试时候,就可以从两个输入域分别取出或者设计一组数据进行就可以达到测试的目的。
如果用户输入的订单类型又不是出口,也不是进口,又是一种什么情况呢,我们继续延伸需求,如果用户输入的订单既不是出口也不是进口,系统将出错并显示出错信息。由此我们可以引入一些概念,就是有效等价类(Valid Class)和无效等价类(Invalid Class)。有效的等价类表示输入是系统接受范围的数据,属于正常的系统行为,而无效等价类表示输入属于错误的数据。当然也可能会有相应的系统行为,比如我们如上所说出错并显示出错信息,还可以提示用户重新输入呢。这样的话,等价类就可以表示为以下三个:
有效等价类:
{订单类型=出口,其他资料=any}
{订单类型=进口,其他资料=any}
无效等价类:
{订单类型=其他,其他资料=any}
接下来给出等价类的划分方法:
1.对于连续的数据范围(比如1<X<999)
为连续范围设计一个有效等价类(1<X<999)
分别为范围之上和之下设计两个无效等价类(X<=1 和X>=999)
2.对于输入是一组值的话
为每个值设计一个有效等价类
为其他非法值设计一个无效等价类
3.对于必须遵守的条件(可能是条件组合)
为必须遵守条件设计一个有效等价类
为其他非法值设计一个或者多个无效等价类
根据输入数据是否属于多余一个等价类,可以把输入域分成为非重叠的(Non-overlapping Partition)和重叠的(Overlapping Partition)两种。
这里给出非重叠和重叠的一些例子:
非重叠:
1. X>100
2. X是A或者B
重叠:
1. X是A或者B,Y是不为空字符串或者null
我们再看看输入是组合条件的情况:
例:X必须是A或者B并且0<Y<100
这里有两个条件,有效等价类应该怎么划分呢?
有效等价类:
{X=A and 0<Y<100}
{X=B and 0<Y<100}
无效等价类:
{X<>A and X<>B}
{Y<=0}
{Y>=100}
确定了等价类之后,我们需要做的就是根据等价类设计Test Case了,以下给出设计等价类Test Case的一些Guidelines:
1.为每个等价类制定一个唯一编号
2.设计Test Case使其尽可能的覆盖尽可能多的有效等价类
3.直到所有的有效等价类都被覆盖
4.为每个无效等价类设计一个Test Case
5.直到所有的无效等价类都被覆盖
再看X<Y ,Z>Y的这个例子,我们换一种方法,可以采用表格的方法来确定等价类:
X<Y | X>=Y | |
Z>Y | x | x |
Z<=Y | x | x |
X<Y |
X>=Y |
Z>Y |
Z<=Y |
X<Y, Z>Y
|
X>=Y, Z>Y |
X>=Y, Z<=Y |
X<Y, Z<=Y
|
很容易看出重叠之处,由此可以得出四个等价类:
{X<Y}
{X>=Y}
{Z>Y}
{Z<=Y}
而根据Test Case的设计原则,我们可以设计一个case覆盖X<Y和Z<=Y,另外一个case覆盖X>=Y和Z>Y,可以减少case的设计。
总结:
根据等价类法方法划分所有的输入必然属于某个等价类。为有效等价类设计case是尽可能的多覆盖等价类,覆盖是否足够要自我把握,等价类方法可以让我们用最少的测试来验证系统的功能,但是值得引起我们注意的是等价类方法并不作用于输出(output)或者结果(effect)。