|
知识路径: > 测试技术的分类 > 白盒测试技术 > 白盒测试方法 >
|
考试要求:掌握
相关知识点:26个
|
|
|
|
|
域测试(Domain Testing)是一种基于程序结构的测试方法。Howden曾对程序中出现的错误进行分类,他将程序错误分为域错误、计算型错误和丢失路径错误三种,这是相对于执行程序的路径来说的。我们知道,每条执行路径对应于输入域的一类情况,是程序的一个子计算。如果程序的控制流有错误,对于某一特定的输入可能执行的是一条错误路径,这种错误称为路径错误,也叫做域错误。如果对于特定输入执行的是正确路径,但由于赋值语句的错误致使输出结果不正确,则称此为计算型错误。
|
|
|
另外一类错误是丢失路径错误。它是由于程序中的某处少了一个判定谓词而引起的。域测试主要是针对域错误进行的程序测试。
|
|
|
域测试的“域”是指程序的输入空间。域测试方法基于对输入空间的分析。自然,任何一个被测程序都有一个输入空间。测试的理想结果就是检验输入空间中的每一个输入元素是否都产生正确的结果。而输入空间又可分为不同的子空间,每一子空间对应一种不同的计算。在考察被测试程序的结构以后,我们就会发现,子空间的划分是由程序中分支语句中的谓词决定的。输入空间的一个元素,经过程序中某些特定语句的执行而结束(当然也可能出现无限循环而无出口),那都是满足了这些特定语句被执行所要求的条件的。
|
|
|
域测试正是在分析输入域的基础上,选择适当的测试点以后进行测试的。
|
|
|
域测试有两个致命的弱点,一是为进行域测试对程序提出的限制过多,二是当程序存在很多路径时,所需的测试点也就很多。
|
|
|
|
符号测试的基本思想是允许程序的输入不仅仅是具体的数值数据,而且包括符号值,这一方法也是因此而得名的。这里所说的符号值可以是基本符号变量值,也可以是这些符号变量值的一个表达式。这样,在执行程序过程中以符号的计算代替了普通测试执行中对测试用例的数值计算。所得到的结果自然是符号公式或是符号谓词。更明确地说,普通测试执行的是算术运算,符号测试执行的则是代数运算。因此符号测试可以认为是普通测试的一个自然的扩充。
|
|
|
符号测试可以看作是程序测试和程序验证的一个折衷方法。一方面,它沿用了传统的程序测试方法,通过运行被测程序来验证它的可靠性。另一方面,由于一次符号测试的结果代表了一大类普通测试的运行结果,实际上是证明了程序接受此类输入后,所得输出是正确的还是错误的。最为理想的情况是,程序中仅有有限的几条执行路径。如果对这有限的几条路径都完成了符号测试,我们就能较有把握地确认程序的正确性了。
|
|
|
从符号测试方法的使用来看,问题的关键在于开发出比传统的编译器功能更强,能够处理符号运算的编译器和解释器。
|
|
|
目前符号测试存在一些未得到圆满解决的问题,如下所示。
|
|
|
|
当采用符号执行方法进行到某一分支点处,分支谓词是符号表达式,这种情况下通常无法决定谓词的取值,也就不能决定分支的走向,需要测试人员做人工干预,或是执行树的方法进行下去。如果程序中有循环,而循环次数又决定于输入变量,那就无法确定循环的次数。
|
|
|
|
数据项的符号值可能是有二义性的。这种情况通常出现在带有数组的程序中。
|
|
|
|
|
如果I=J,则C=3;否则,C=2+A。但由于使用符号值运算,这时无法知道I是否等于J。
|
|
|
|
符号测试中经常要处理符号表达式。随着符号执行的继续,一些变量的符号表达式会越来越庞大。特别是当符号执行树很大,分支点很多时,路径条件本身变成一个非常长的表达式。如果能够有办法将其化简,自然会带来很大好处。但如果找不到化简的办法,那将给符号测试的时间和运行空间带来大幅度的增长,甚至使整个问题的解决遇到难以克服的困难。
|
|
|
|
分析程序中的路径是指:检验程序从入口开始,执行过程中经历的各个语句,直到出口。这是白盒测试最为典型的问题。着眼于路径分析的测试可称为路径测试。完成路径测试的理想情况是做到路径覆盖。对于比较简单的小程序实现路径覆盖是可能做到的。但是如果程序中出现多个判断和多个循环,可能的路径数目将会急剧增长,达到天文数字,以至于实现完全路径覆盖是不可能做到的。
|
|
|
为了解决这一问题,我们必须舍掉一些次要因素,对循环机制进行简化,从而极大地减少路径的数量,使得覆盖这些有限的路径成为可能。我们称简化循环意义下的路径覆盖为Z路径覆盖。
|
|
|
这里所说的对循环化简,是指限制循环的次数。无论循环的形式和实际执行循环体的次数多少,我们只考虑循环一次和零次两种情况。即只考虑执行时进入循环体一次和跳过循环体这两种情况。如下图(a)和(b)所示表示了两种最典型的循环控制结构。前者先作判断,循环体B可能执行(假定只执行一次),也可能不执行。这就如同如下图(c)所示的条件选择结构一样。后者先执行循环体B(假定也执行一次),再经判断转出,其效果也与(c)中给出的条件选择结构只执行右支的效果一样。
|
|
|
|
|
对于程序中的所有路径可以用路径树来表示,具体表示方法这里忽略。当得到某一程序的路径树后,从其根结点开始,一次遍历,再回到根结点时,把所经历的叶结点名排列起来,就得到一个路径。如果我们设法遍历了所有的叶结点,就得到了所有的路径。
|
|
|
当得到所有的路径后,生成每个路径的测试用例,就可以做到Z路径覆盖测试。
|
|
|
|
程序变异方法与前面提到的结构测试和功能测试都不一样,它是一种错误驱动测试。所谓错误驱动测试,是指该方法是针对某类特定程序错误的。经过多年的测试理论研究和软件测试的实践,人们逐渐发现要想找出程序中所有的错误几乎是不可能的。比较现实的解决办法是将错误的搜索范围尽可能地缩小,以利于专门测试某类错误是否存在。这样做的好处在于,便于集中目标于对软件危害最大的可能错误,而暂时忽略对软件危害较小的可能错误。这样可以取得较高的测试效率,并降低测试的成本。
|
|
|
错误驱动测试主要有两种,即程序强变异和程序弱变异。为便于测试人员使用变异方法,一些变异测试工具被开发出来。关于程序变异测试方法,请参见清华大学出版社出版的《软件测试技术》一书。
|
|
|