3.9.测试过程控制 

    在测试过程中,通过对缺陷数据库进行分析可以确定测试的状态。另外,通过让测试人员填写测试工作周报,可以对项目进展状况进行反馈。 

3.9.1 缺陷数据分析 

    提示和技巧: 
    在开发过程和稳定阶段是否有过多的未处理缺陷,这可能说明开发的资源不够,或者有其它问题。 
    如何确定项目中是否有过多的缺陷。 
    测试人员是否积极发现缺陷,或者过分积极。 
    在每个时间点上,系统是否稳定。 
    系统哪些部分的缺陷集中。 
    在系统发行时修复了多少缺陷。 
    哪些类型的缺陷普遍。 

3.9.2 测试工作周报 

    提示和技巧: 
    周报中应包括哪些信息。 
    如何填写工作周报。 
    谁负责查看工作周报。 
    以上详细的描述了,测试过程中可能遇到的或者必须提前安排的工作内容,有一些项是要在工作过程中陆续充实的,有一些是需要提前给出解决办法的,在制定计划过程中,请依据实际情况进行书写。 

4 测试计划 

4.1 整体测试策略 

    本节的目的是说明计划中使用的基本的测试过程。

提示和技巧: 
    是否使用里程碑技术和在测试过程中验证每个模块?或者是什么都不做,只是普通的测试而已。 
    测试人员是否在项目开发初期开始工作?或者测试人员只在系统开发完后,才开始测试。 
    是否明显的界定出单元,集成,系统,验收测试阶段? 
    自动测试工作是否进行? 
    对于像压力,性能,兼容性等的测试项目,放到那一个测试区间内,有什么质量要求? 

4.2 测试范围 

    通常说明什么是要测试的,什么是不要测试的是非常重要的。明确规定这些问题后,测试人员对该做什么有一个清晰的认识。 
    提示和技巧: 
    需要特别测试那些部分? 
    那些部分不需要测试,为什么? 
    测试人员是否需要测试内容以及相关部分? 
    是否要验证每个模块的稳定性? 
    是否有理论上应该测试的,但是测试环境无法进行测试的内容? 
    对于产品附带的文档,测试人员是否需要检查? 

4.3 质量目标 

    围绕软件质量,有几种不同的说法。第一个是质量是一种的标准,对所有的系统必须等同处理。事实上,质量是相对的而且是和产品相关的概念。例如,多媒体产品的质量目标倾向于精美的表示和适当的内容,而应用系统可能倾向于易用性、健壮性和适用于不同的任务。质量目标可能是动态的。在项目进行过程中,会由于市场压力、新的机会和功能改变而重新设定质量目标。 
    另一种有关软件质量的说法是,定义和衡量系统质量是测试部门一个部门的事。实际上,建立质量标准是所有职能部门共同努力的结果。测试、开发、系统使用部门、用户教育、系统支撑必须为建立和维护系统的质量标准做出自己的贡献。每个部门必须对自己了解的部分做出相应的质量定义。例如,测试和开发部门对系统质量的衡量标准主要是健壮性和正确性。用户部门可能对易用性方面比较熟悉。 
    后,质量不仅是衡量系统的功能或性能是否正常。对系统来说,在开发过程中尽早建立全面的质量标准与系统的及时发布是一样重要的。质量目标是一个强有力的工具,应该在系统开发过程中尽早建立。一个定义准确的质量目标在以后的产品开发过程中帮助决策。例如,系统是否能够正式发行?在代码完成后,应该修复那些缺陷?在系统完成后那种类型的测试是合适的。 
    提示: 
    质量目标应该是一个确实可行的软件质量描述,在确定之前应该同相关人员达成一致的意见,不要等到发货的时候才发现大家对其的理解有分歧,这时测试人员会非常被动,在达成一致意见后,当开发人员和测试人员有分歧时,可以使用质量目标作为衡量的标准。 

4.4 测试计划 

    一般情况下测试活动大致分成四个部分:单元测试,集成测试,系统测试,验收测试。下面具体介绍一下测试计划的书写方法,工作过程中可以依据实际情况进行删减和补充。 
4.4.1 单元测试 

    单元测试是代码一级的测试,主要依赖于开发人员进行。 
    单元测试的对象是软件设计的小单位——模块。单元测试的依据是详细设计描述,单元测试应对模块内所有重要的控制路径设计测试用例,以便发现模块内部的错误。单元测试多采用白盒测试技术,系统内多个模块可以并行地进行测试。 

一、单元测试任务 

    单元测试任务包括: 
     (1)模块接口测试; 
     (2)模块局部数据结构测试; 
     (3)模块边界条件测试; 
     (4)模块中所有独立执行通路测试; 
     (5)模块的各条错误处理通路测试。 
    模块接口测试是单元测试的基础。只有在数据能正确流入、流出模块的前提下,其他测试才有意义。测试接口正确与否应该考虑下列因素: 
     (1)输入的实际参数与形式参数的个数是否相同; 
     (2)输入的实际参数与形式参数的属性是否匹配; 
     (3)输入的实际参数与形式参数的量纲是否一致; 
     (4)调用其他模块时所给实际参数的个数是否与被调模块的形参个数相同; 
     (5)调用其他模块时所给实际参数的属性是否与被调模块的形参属性匹配; 
     (6)调用其他模块时所给实际参数的量纲是否与被调模块的形参量纲一致; 
     (7)调用预定义函数时所用参数的个数、属性和次序是否正确; 
     (8)是否存在与当前入口点无关的参数引用; 
     (9)是否修改了只读型参数; 
     (10)对全程变量的定义各模块是否一致; 
     (11)是否把某些约束作为参数传递。 
    如果模块内包括外部输入输出,还应该考虑下列因素: 
     (1)文件属性是否正确; 
     (2)OPEN/CLOSE语句是否正确; 
     (3)格式说明与输入输出语句是否匹配; 
     (4)缓冲区大小与记录长度是否匹配; 
     (5)文件使用前是否已经打开; 
     (6)是否处理了文件尾; 
     (7)是否处理了输入/输出错误; 
     (8)输出信息中是否有文字性错误; 
    检查局部数据结构是为了保证临时存储在模块内的数据在程序执行过程中完整、正确。局部数据结构往往是错误的根源,应仔细设计测试用例,力求发现下面几类错误: 
     (1)不合适或不相容的类型说明; 
     (2)变量无初值; 
     (3)变量初始化或省缺值有错; 
     (4)不正确的变量名(拼错或不正确地截断);  
     (5)出现上溢、下溢和地址异常。 
    在模块中应对每一条独立执行路径进行测试,单元测试的基本任务是保证模块中每条语句至少执行一次。此时设计测试用例是为了发现因错误计算、不正确的比较和不适当的控制流造成的错误。此时基本路径测试和循环测试是常用且有效的测试技术。计算中常见的错误包括: 
     (1)误解或用错了算符优先级; 
     (2)混合类型运算; 
     (3)变量初值错; 
     (4)精度不够; 
     (5)表达式符号错。 
    比较判断与控制流常常紧密相关,测试用例还应致力于发现下列错误:  
     (1)不同数据类型的对象之间进行比较; 
     (2)错误地使用逻辑运算符或优先级; 
     (3)因计算机表示的局限性,期望理论上相等而实际上不相等的两个量相等; 
     (4)比较运算或变量出错; 
     (5)循环终止条件或不可能出现; 
     (6)迭代发散时不能退出; 
     (7)错误地修改了循环变量。 
    一个好的设计应能预见各种出错条件,并预设各种出错处理通路,出错处理通路同样需要认真测试,测试应着重检查下列问题: 
     (1)输出的出错信息难以理解; 
     (2)记录的错误与实际遇到的错误不相符; 
     (3)在程序自定义的出错处理段运行之前,系统已介入; 
     (4)异常处理不当; 
     (5)错误陈述中未能提供足够的定位出错信息。 
    边界条件测试是单元测试中后,也是重要的一项任务。众的周知,软件经常在边界上失效,采用边界值分析技术,针对边界值及其左、右设计测试用例,很有可能发现新的错误。 

二、单元测试过程 

    一般认为单元测试应紧接在编码之后,当源程序编制完成并通过复审和编译检查,便可开始单元测试。测试用例的设计应与复审工作相结合,根据设计信息选取测试数据,将增大发现上述各类错误的可能性。在确定测试用例的同时,应给出期望结果。 
    应为测试模块开发一个驱动模块(driver)和(或)若干个桩模块(stub),下图显示了一般单元测试的环境。驱动模块在大多数场合称为“主程序”,它接收测试数据并将这些数据传递到被测试模块,被测试模块被调用后,“主程序”打印“进入-退出”消息。 
    驱动模块和桩模块是测试使用的软件,而不是软件产品的组成部分,但它需要一定的开发费用。若驱动和桩模块比较简单,实际开销相对低些。遗憾的是,仅用简单的驱动模块和桩模块不能完成某些模块的测试任务,这些模块的单元测试只能采用下面讨论的集成测试方法。 
    提高模块的内聚度可简化单元测试,如果每个模块只能完成一个,所需测试用例数目将显著减少,模块中的错误也更容易发现。单元测试计划的编写应该含盖上述的内容,单形式不限,对于测试的数据应该有效的予以保留,为今后进行数据分析作准备。 
 

4.4.2 集成测试 

    集成测试针对的是各个相关模块的组合测试,终的目标是将整个系统正确的组合成功,没有明显的模块之间的匹配问题。 
    时常有这样的情况发生,每个模块都能单独工作,但这些模块集成在一起之后却不能正常工作。主要原因是,模块相互调用时接口会引入许多新问题。例如,数据经过接口可能丢失;一个模块对另一模块可能造成不应有的影响;几个子功能组合起来不能实现主功能;误差不断积累达到不可接受的程度;全局数据结构出现错误,等等。集成测试是组装软件的系统测试技术,按设计要求把通过单元测试的各个模块组装在一起之后,进行集成测试以便发现与接口有关的各种错误。 
    某设计人员习惯于把所有模块按设计要求一次全部组装起来,然后进行整体测试,这称为非增量式集成。这种方法容易出现混乱。因为测试时可能发现一大堆错误,为每个错误定位和纠正非常困难,并且在改正一个错误的同时又可能引入新的错误,新旧错误混杂,更难断定出错的原因和位置。与之相反的是增量式集成方法,程序一段一段地扩展,测试的范围一步一步地增大,错误易于定位和纠正,界面的测试亦可做到完全彻底。下面讨论两种增量式集成方法。 

一、自顶向下集成 

    自顶向下集成是构造程序结构的一种增量式方式,它从主控模块开始,按照软件的控制层次结构,以深度优先或广度优先的策略,逐步把各个模块集成在一起。深度优先策略首先是把主控制路径上的模块集成在一起,至于选择哪一条路径作为主控制路径,这多少带有随意性,一般根据问题的特性确定。以下图为例,若选择了左一条路径,首先将模块 M1,M2,M5 和 M8 集成在一起,再将 M6 集成起来,然后考虑中间和右边的路径。广度优先策略则不然,它沿控制层次结构水平地向下移动。仍以下图为例,它首先把M2、M3 和M4 与主控模块集成在一起,再将M5和M6 和其他模块集资集成起来。 
 自顶向下集成测试的具体步骤为: 
     (1) 以主控模块作为测试驱动模块,把对主控模块进行单元测试时引入的所有桩模块用实际模块替代; 
     (2)依据所选的集成策略(深度优先或广度优先),每次只替代一个桩模块;  
     (3)每集成一个模块立即测试一遍; 
     (4)只有每组测试完成后,才着手替换下一个桩模块; 
     (5)为避免引入新错误,须不断地进行回归测试(即全部或部分地重复已做过的测试)。 
    从第二步开始,循环执行上述步骤,直至整个程序结构构造完毕。 
    自顶向下集成的优点在于能尽早地对程序的主要控制和决策机制进行检验,因此较早地发现错误。缺点是在测试较高层模块时,低层处理采用桩模块替代,不能反映真实情况,重要数据不能及时回送到上层模块,因此测试并不充分。解决这个问题有几种办法,第一种是把某些测试推迟到用真实模块替代桩模块之后进行,第二种是开发能模拟真实模块的桩模块;第三种是自底向上集成模块。第一种方法又回退为非增量式的集成方法,使错误难于定位和纠正,并且失去了在组装模块时进行一些特定测试的可能性;第二种方法无疑要大大增加开销;第三种方法比较切实可行,下面专门讨论。 

二、自底向上集成 

    自底向上测试是从“原子”模块(即软件结构低层的模块)开始组装测试,因测试到较高层模块时,所需的下层模块功能均已具备,所以不再需要桩模块。 
    自底向上集成测试的步骤分为: 
     (1)把低层模块组织成实现某个子功能的模块群(cluster); 
     (2)开发一个测试驱动模块,控制测试数据的输入和测试结果的输出;  
     (3)对每个模块群进行测试; 
     (4)删除测试使用的驱动模块,用较高层模块把模块群组织成为完成更大功能的新模块群。 
    从第一步开始循环执行上述各步骤,直至整个程序构造完毕。 
    自底向上集成方法不用桩模块,测试用例的设计亦相对简单,但缺点是程序后一个模块加入时才具有整体形象。它与自顶向集成测试方法优缺点正好相反。因此,在测试软件系统时,应根据软件的特点和工程的进度,选用适当的测试策略,有时混和使用两种策略更为有效,上层模块用自顶向下的方法,下层模块用自底向上的方法。 
    此外,在集成测试中尤其要注意关键模块,所谓关键模块一般都具有下述一或多个特征: ①对应几条需求;②具有高层控制功能;③复杂、易出错;④有特殊的性能要求。关键模块应尽早测试,并反复进行回归测试。 
以上介绍了一些进行集成测试的具体方案,不同的项目,测试经理可以根据实际情况选择。但是在实施之前,必须给出实施的步骤和时间规划。 

4.4.3 系统测试 

    系统测试应该由若干个不同测试组成,目的是充分运行系统,验证系统各部件是否都能正常工作并完成所赋予的任务。下面简单介绍几类系统测试。 

 (1)验证测试 

    以前期的用户需求规格说明书的内容为依据,验证系统是否正确无误的实现了需求中的全部内容。 

 (2)强度测试 

    强度测试检查程序对异常情况的抵抗能力。强度测试总是迫使系统在异常的资源配置下运行,验证系统的健壮性是否可靠。  

 (3)性能测试 

    对于那些实时系统,软件部分即使满足功能要求,也未必能够满足性能要求,虽然从单元测试起,每一测试步骤都包含性能测试,但只有当系统真正集成之后,在真实环境中才能全面、可靠地测试运行性能系统性能测试是为了完成这一任务。性能测试有时与强度测试相结合,经常需要其他软硬件的配套支持。


编辑评论意见 (田俊国) 

    测试和过程控制是构筑软件质量的两个重要环节,也是软件工程化的重要标志。然而,我国大多数中小型软件企业,对软件测试的重视还很不够, 媒体上介绍软件测试的文章也很少。因此,很多软件工程师对测试知之甚少,甚至对测试心存偏见,不少人认为测试工程师比开发工程师低一个档次。而这一点在国外正好相反,在美国,没有三年以上软件开发经验的人是不能做测试工程师的。 
    本文比较系统地介绍了软件测试的方方面面,有技术也有方法;有理论也有作者的实战体会;更可贵的是专业的测试理念贯穿全文,比如: 测试的目的是找错误,但不仅仅局限于找错误;测试是在软件开发过程的末尾进行的,但测试人员却要从需求分析阶段介入项目组… …  
    文章深入浅出,通俗易懂, 的确是一篇不可多得的软件测试知识普及性文章。相信软件开发同行们会从中大受裨益,参加软件专业资格水平考试的朋友们更是不可不读。

编辑评论意见 (胡志华) 

    当我还是一名程序员的时候,我也曾为测试而焦头烂额,我也曾对测试员刁难和不顾;当我作为测试员的角色时,也因无从下手而懊恼,面对测试计划也表示怀疑和不解;我也曾制定测试计划、编写测试用例,主持或参与对软件或网站的验收。相信我所遭遇的艰难,您也曾遭遇或者您也许会遭遇,在这个时候,我们都需要交流和学习,也许阅读这篇文章是一个选择啊。
    本文虽然旨在论述测试计划的编写,但是对于测试的其他方面也做了详细的介绍,例如测试的一些基本概念,测试的几种类型,测试过程的控制等。