软件测试策略把软件测试案例的设计方法集成到一系列已经周密计划的步骤中去,从而使软件的开发得以成功地完成。同样重要的事,软件测试策略为软件开发人员、质量保证组织和客户提供了一个路线图,这个路线图描述了测试的步骤,以及当这些步骤在计划和实施的过程中,需要多少工作量、时间和资源。因此,任何测试策略都必须和测试计划、测试案例设计、测试执行和测试结果数据的收集与分析结合在一起。
一 集成测试
一个在软件世界里初出茅庐的年轻人可能在所有的模块都已经完成单元测试之后会问这样一个似乎很合理的问题:“如果他们每一个都能单独工作的很好,那么你为什么要怀疑把它们放在一起就不能正常工作呢?”当然,这个问题就在于“把它们放在一起”----接口相连。数据可能在通过接口的时候丢失;一个模块可能对另一个模块产生无法预料的副作用;当子函数被连到一起的时候,可能不能达到预期的功能;在单个模块中可以接受的不精确性在连起来之后可能会扩大到无法接受的程度;全局数据结构可能也会存在问题。不幸的事,还有很多很多。
集成测试是通过测试发现和接口有关的问题来构造程序的系统化技术,他的目标是把通过了单元测试的模块拿来,构造一个设计总所描述的程序结构。
通常存在进行非增量集成的倾向,也就是说,使用“一步到位”的方法来构造程序。所有的构件都预先结合在一起,整个程序作为一个整体来进行测试,其后的结果通常是混乱不看!会遇到许许多多的错误,错误的修正也是非常困难的,因为在整个程序的庞大区域中要分离出一个错误是很复杂的。一旦这些错误被修正之后,就马上会有新的错误出现,这个过程会继续下去,而且看上去似乎是个无限循环。
增量集成是一步到位的方法的对立面。程序先分成小的部分进行构造和测试,这个时候错误比较容易分离和修正,接口也更容易进行彻底地测试,而且也可以使用一种系统化的测试方法。
1.1 自顶向下集成
自顶向下集成测试时一直构造结构的增量方法。模块集成的顺序是首先集成主控模块(主程序),然后按照控制层次结构向下进行集成。从属于(和间接从属于)主控模块的模块按照深度优先或者宽度优先的方式集成到整个结构中去。
深度优先集成首先集成结构中的一个主控路径下的所有模块。主控路径的选择是有些随意的,它依赖于应用程序的特性,例如,选择最左边的路径,模块M1、M2和M5将首先进行集成,然后是M8或者M6(如果对M2的适当的功能是必要的),然后,开始构造中间的右边的控制路径。宽度优先集成首先沿着水平方向,把每一层中的所有直接从属于上一层模块的模块集成起来,模块M2、M3和M4首先进行集成,然后是下层的M5和M6,然后继续。
集成的整个过程有下列5个步骤来完成:
1主控模块被利用作测试驱动程序,所有的桩模块替换为直接从属于主控模块的模块。
2根据集成的实现方法(如深度或宽度优先),下层的桩模块一次一个地被替换为真正的模块。
3在每一个模块集成的时候都要进行测试。
4在完成了每一次测试之后,又一个桩模块被用真正的模块替换。
5可以用回归测试来保证没有引进新的错误。
整个过程号第2步循环继续进行,直至这个系统结构被构造完成。
自顶向下集成策略在测试过程中的早期验证主要的控制和决策点。在一个好的因子化的程序结构中,决策的确定性往往发生在层次结构中的高层,因此首先会被逮到。如果主控制的确存在问题,尽早地发现它是很重要的。如果选择了深度优先集成,软件的某个完整的功能会被实现和证明,例如,考虑一个经典的事务性结构,在这个结构中,有一系列复杂的交互式输入要通过一条输入路径请求、获得和验证,这条输入路径就可以用自顶向下的方式来进行集成。所有输入处理(为了后续的事务分派)可以在其他结构元素被集成前展示出来。早期的对功能性的战士对开发人员和客户来说都是会增加信心的。
自顶向下策略似乎相对来说不是很复杂,但是在实践过程中,可能会出现逻辑上的问题。最普通的这类问题出现在当高层测试需要首先对较低层次的足够测试后才能完成的时候。在自顶向下测试开始的时候,桩模块代替了底层的模块,因此,在程序结构中就不会有重要的数据项上传递,测试者只有下面的三种选择:一是把测试推辞到桩模块被换成实际的模块之后再进行,而是开发能够实现有限功能的用来模拟实际模块的桩模块,三是从层次结构的最高底部向上来对软件进行集成。
第一种实现方法(把测试推迟到桩模块被换成实际的模块之后再进行)使我们失去了对许多在特定测试和特定模块组合之间的对应性的控制,这样可能导致在确定错误发生原因是的困难性,并且会违背自顶向下方法的高度受限的本质。第二种方法是可行的,但是会导致很大的额外开销,因为桩模块会变得越来越复杂。第三种方法,也就是自底向上测试。