|
白盒测试的动态测试要根据程序的控制结构设计测试用例,其原则是:
|
|
|
|
|
|
|
但是对一个具有多重选择和循环嵌套的程序,不同的路径数目可能是天文数字。而且即使精确地实现了白盒测试,也不能断言测试过的程序完全正确。如下图所示的穷举测试流程图,其中包括了一个执行达20次的循环,它所包含的不同执行路径数高达520条,假使有这么一个测试程序,对每一条路径进行测试需要1ms,假设一天工作24小时,一年工作365天,若要对它进行穷举测试,也需要3024年的时间。
|
|
|
|
|
以上的情况说明,实现穷举测试的工作量过大,需要的时间过长,实施起来是不现实的。任何软件开发项目都要受到期限、费用、人力和机时等条件的限制,尽管我们以为为了充分揭露程序中的所有隐藏错误,彻底的做法是针对所有可能的数据进行测试,但事实告诉人们,这样做是不可能的。
|
|
|
在测试阶段既然穷举测试不可行,为了节省时间和资源,提高测试效率,就必须精心设计测试用例,也就是从数量巨大的可用测试用例中精心挑选少量的测试数据,使得采用这些测试数据就能够达到最佳的测试效果。
|
|
|
本节和下节将介绍几种实用的白盒测试用例设计方法:逻辑覆盖法和基本路径测试法。
|
|
|
逻辑覆盖是通过对程序逻辑结构的遍历实现程序的覆盖。它是一系列测试过程的总称,这组测试过程逐渐进行越来越完整的通路测试。从覆盖源程序语句的详尽程度分析,逻辑覆盖标准包括以下不同的覆盖标准:语句覆盖(SC)、判定覆盖(DC)、条件覆盖(CC)、条件判定组合覆盖(CDC)、多条件覆盖(MCC)和修正判定条件覆盖(MCDC)。
|
|
|
为便于理解,我们使用如下所示的程序(用C语言书写),如下图所示的是其流程图。
|
|
|
|
|
|
|
|
为了暴露程序中的错误,程序中的每条语句至少应该执行一次。因此,语句覆盖(Statement Coverage)的含义是:选择足够多的测试数据,使被测程序中每条语句至少执行一次。
|
|
|
为了使上述程序中的每条语句都能够至少执行一次,我们可以构造以下测试用例即可实现:
|
|
|
|
从程序中的每条语句都得到执行这一点看,语句覆盖的方法似乎能够比较全面地检验每一条语句,但是语句覆盖对程序执行逻辑的覆盖很低,这是其最严重的缺陷。
|
|
|
假如,这一程序段中判定的逻辑运算有问题,例如,判定的第一个运算符“&&”错写成运算符“||”,或第二个运算符“||”错写成运算符“&&”,这时使用上述的测试用例仍然可以达到100%的语句覆盖,上述的逻辑错误无法发现。
|
|
|
|
|
比语句覆盖稍强的覆盖标准是判定覆盖(Decision Coverage)。判定覆盖的含义是:设计足够的测试用例,使得程序中的每个判定至少都获得一次“真值”或“假值”,或者说使得程序中的每一个取“真”分支和取“假”分支至少经历一次,因此判定覆盖又称为分支覆盖。
|
|
|
除了双值的判定语句外,还有多值判定语句,如case语句,因此判定覆盖更一般的含义是:使得每一个判定获得每一种可能的结果至少一次。
|
|
|
以上述代码为例,构造以下测试用例即可实现判定覆盖标准:
|
|
|
|
|
应该注意到,上述两组测试用例不仅满足了判定覆盖,而且满足了语句覆盖,从这一点看,判定覆盖要比语句覆盖更强一些。但是同样地,假如这一程序段中判定的逻辑运算有问题,如下表所示,判定的第一个运算符“&&”错写成运算符“||”或第二个运算符“||”错写成运算符“&&”,这时使用上述的测试用例可以达到100%的判定覆盖,仍然无法发现上述的逻辑错误。因此需要更强的逻辑覆盖标准。
|
|
|
|
|
|
在设计程序中,一个判定语句是由多个条件组合而成的复合判定,在如上图所示参考例子流程图的程序中,判定(a)AND(b OR c)包含了三个条件:a, b和c。为了更彻底地实现逻辑覆盖,可以采用条件覆盖(Condition Coverage)的标准。条件覆盖的含义是:构造一组测试用例,使得每一判定语句中每个逻辑条件的可能值至少满足一次。
|
|
|
按照这一定义,上述例子要达到100%的条件覆盖,可以使用以下测试用例:
|
|
|
|
|
仔细分析可以发现,上述用例在满足条件覆盖的同时,把判定的两个分支也覆盖了,这样是否可以说,达到了条件覆盖也就必然实现了判定覆盖呢?
|
|
|
|
|
|
我们会发现覆盖了条件的测试用例并没有覆盖分支,如下表所示。为解决这一矛盾,需要对条件和分支兼顾。
|
|
|
|
|
|
条件判定组合覆盖的含义是:设计足够的测试用例,使得判定中每个条件的所有可能(真/假)至少出现一次,并且每个判定本身的判定结果(真/假)也至少出现一次。
|
|
|
对于如上图所示的例子,选用以下的两组测试用例可以符合条件判定组合覆盖标准:
|
|
|
|
|
但是条件判定组合覆盖也存在一定的缺陷,例如,判定的第一个运算符“&&”错写成运算符“||”或第二个运算符“||”错写成运算符“&&”,如下表所示,这时使用上述的测试用例仍然可以达到100%的条件判定组合覆盖,上述的逻辑错误无法发现。
|
|
|
|
|
|
多条件覆盖也称条件组合覆盖,它的含义是:设计足够的测试用例,使得每个判定中条件的各种可能组合都至少出现一次。显然满足多条件覆盖的测试用例是一定满足判定覆盖、条件覆盖和条件判定组合覆盖的。
|
|
|
对于如下图所示的例子,判定语句中有三个逻辑条件,每个逻辑条件有两种可能取值,因此共有23=8种可能组合,如下表所示的测试用例保证了多条件覆盖。
|
|
|
|
|
|
|
由上可知,当一个程序中判定语句较多时,其条件取值的组合数目是非常大的。
|
|
|
|
修正条件判定覆盖是由欧美的航空/航天制造厂商和使用单位联合制定的“航空运输和装备系统软件认证标准”,目前在国外的国防、航空航天领域应用广泛。这个覆盖度量需要足够的测试用例来确定各个条件能够影响到包含的判定的结果。它要求满足两个条件:首先,每一个程序模块的入口和出口点都要考虑至少要被调用一次,每个程序的判定到所有可能的结果值要至少转换一次;其次,程序的判定被分解为通过逻辑操作符(and、or)连接的bool条件,每个条件对于判定的结果值是独立的。
|
|
|
对于如下图所示的例子,可以设计如下表中的8个用例,在此基础上,按照MCDC的要求选择需要的用例。
|
|
|
|
|
|
|
从表中我们可以看出,布尔变量a可以通过用例1和5达到MCDC的要求(用例2和6或用例3和7也可以满足相应要求),变量b可以通过用例2和4达到MCDC的要求,变量c可以通过用例3和4达到MCDC的要求,因此使用用例集{1,2,3,4,5}即可满足MCDC的要求。显而易见,这不是惟一的用例组合。
|
|
|