▶6.2.2.1 软件测试的过程
软件测试阶段的过程(见图6-1)。每个圆圈代表一种复杂的变换。这个阶段输入的信息有两种类型:
(1)软件配置文件集:指要测试的软件,包括需求说明书,设计规格说明书和源程序清单等。
(2)测试配置:包括测试计划、测试过程、测试用例以及预期的结果。实际上测试配置是软件配置的一个子集,最终交出的软件配置应该包括上述测试配置以及测试的实际结果和测试的记录。
图6-1 软件测试过程模型
测试得出的结果和预期的结果进行比较,若不一致则很可能是程序中有错误,设法确定错误的位置并改正它,这就是测试的任务。通常由程序的编写者负责和调试。由于测试本身的不确定性,常常难以准确安排测试日期表。
对测试结果进行收集和评价后,软件可靠性所能达到的质量指标也就清楚了。如果经常出现要求修改设计的严重错误,那么软件的质量和可靠性则是值得怀疑的,应该做进一步的仔细测试。另一种情况是软件功能看起来完成得很好,遇到问题也容易修正,但仍应该考虑以下两种可能:
(1)软件的可靠性是可以接受的。
(2)所进行的测试尚不足以发现严重的错误。
如果经过测试,一个错误也没有被发现,则很可能是由于测试配置思考不充分,以致不能暴露软件中潜藏的错误。
▶6.2.2.2 软件测试的步骤
软件测试大体可以分为四步:单元测试、集成测试、确认测试和系统测试。它们依次被实现,测试步骤的模式(见图6-2)。
图6-2 软件测试步骤模型
软件测试阶段的全面计划以及对特定测试的描述,都要写成测试报告,作为软件文档的一个重要部分。下面对具体测试步骤进行介绍。
▶1.单元测试
单元测试集中检查软件设计的最小单元——模块,即对各个模块进行测试,通常称为“分调”,它以详细设计描述为指南,对重要的控制路径进行测试,用以发现错误。单元测试总是使用白盒测试法,可以同时对多个模块并行进行测试。
单元测试是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java中单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
在单元测试过程中,与单元测试联系起来的另外一些开发活动包括代码走读(Codereview),静态分析(Static analysis)和动态分析(Dynamic analysis)。静态分析就是对软件的源代码进行研读,查找错误或收集一些度量数据,并不需要对代码进行编译和执行。动态分析就是通过观察软件运行时的动作来提供执行跟踪、时间分析,以及测试覆盖度方面的信息。
单元测试在开发和复审源程序代码,并检查语法正确性之后,应根据软件设计信息,设计单元测试用例,使得测试用例有可能发现上述各类错误,另外,每个测试用例还应有一个预期的结果。
单元测试对象是模块,模块不是一个独立的程序,因此模块自己不能运行,要靠其他部分来调用和驱动,这样就要为每个单元测试开发两个软件:驱动程序和连接程序。
①驱动程序。驱动程序实际上相当于一个主程序,它接收不同测试用例的数据,并把这些数据传送给测试的模块,最后打印结果。
②连接程序。连接程序用来代替由被测试模块所调用的模块。
例如,某个程序有5个模块(见图6-3)。要测试模块B就需要设计一个驱动程序,把测试用例当作输入送给模块B,同时驱动程序还必须显示模块B执行后产生的结果。此外,由于模块B要调用模块E,用什么方法能够证明模块E已被B调用?这就是连接程序要做的工作。所以应模拟模块E的功能编写一个连接程序,保证返回模块B的信息是正确的。
图6-3 待测试模块
驱动程序和连接程序在软件运行后就不再被使用了,也就是说为了单元测试,这两者都是必须开发的软件,但是它们不与最终的软件产品一起交付用户。如果驱动软件和连接软件设计得简单,那么这种测试所需的费用就少,实际上,许多模块不能用简单的软件进行充分的单元测试,在这种情况下,完全的测试可以放到集成测试步骤后再进行。
当设计的模块具有高聚合时,单元测试就变得简单了。若一个模块只实现一种功能,测试项目就会减少,还可能更容易地发现和预测错误。
▶2.集成测试
在所有模块都通过了单元测试后,各个模块工作都很正常,那么为什么把它们装配在一起以后,仍会怀疑它们能否正常的工作?这里有一个接口问题,如数据穿过接口时可能会丢失,这个模块可能会破坏另一个模块的功能,把子功能组装起来可能不产生所要求的主功能,全程数据结构可能出现问题等。还有一个误差积累问题,单个可以接受的误差,装配以后可能会放大(或积累)到不可接受的程度。这类问题经常出现,所以必须进行集成测试。
集成测试(也称组装测试、联合测试)是单元测试的逻辑扩展。它最简单的形式是:把两个已经过测试过的单元组合成一个组件,测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合为程序的更大部分。方法是测试片段的组合,并最终扩展成进程,将模块与其他组的模块一起测试。最后,将构成进程的所有模块一起测试。此外,如果程序由多个进程组成,应该成对测试它们,而不是同时测试所有进程。(www.xing528.com)
集成测试是在单元测试的基础上,测试在将所有的软件单元按照概要设计规格说明的要求组装成模块、子系统或系统的过程中各部分工作是否达到实现相应技术指标及要求的活动。也就是说,在集成测试之前,单元测试应该已经完成,集成测试中所使用的对象应该是已经经过单元测试的软件单元。这一点很重要,因为如果不经过单元测试,那么集成测试的效果将会受到很大影响,并且会大幅度增加软件单元代码纠错的代价。
集成测试是单元测试的逻辑扩展。在现实方案中,集成是指多个单元的聚合,许多单元组合成模块,而这些模块又聚合成程序的更大部分,如子系统或系统。集成测试采用的方法是测试软件单元的组合能否正常工作,以及与其他组的模块能否集成起来工作。最后,还要测试构成系统的所有模块组合能否正常工作。集成测试所持的主要标准是总体设计的输出文档《软件概要设计规格说明》,任何不符合该说明的程序模块行为都应该加以记载并上报。
集成测试是用于装配软件的一种系统化的技术,要在软件装配的同时进行测试,用以发现与接口相联系的问题,目的是将经过单元测试的模块构成一个符合设计要求的软件结构。集成测试技术有自顶向下和自底向上结合两种测试方法。
集成测试方法的选择决定于软件的特点,有时也取决于任务的进度。一般来说,工程上采用组装的方法,即对软件结构的较上层使用自顶向下的结合方法,对下层使用自底向上的结合方法。
▶3.确认测试
在集成测试之后,软件已经装配完成,接口错误也已经发现并纠正,这时可以开始对软件进行确认测试。确认测试运用黑盒测试的方法,验证被测软件是否满足用户需求。对软件的功能和性能要求在软件需求规格说明书中已经明确规定,它包含的信息就是软件确认测试的基础。
在确认测试过程中还有一项重要的工作,就是对软件配置进行审查(见图6-4)。
图6-4 软件配置审查
审查的目的在于保证软件配置的所有程序和文档正确、完整而且两者要一致。
在所有确认测试全部完成之后,可能出现两种情况:
①功能和性能与规格说明一致,可以接受。
②发现与规格说明不一致,这时需要列出一张缺陷表。如果要在此时进行修改,工作量就大了。通常需要和用户协商,以确定解决在这个阶段发现的问题和错误的办法。
▶4.系统测试
软件仅是计算机系统中的一个元素,最终总是要把软件与其他系统元素结合在一起,进行一系列系统组装测试和系统确认测试。系统测试时软件设计和测试期间所采取的步骤,使软件结合到其他系统中成功的可能性增加,如果在系统测试时发现错误将很难修改。
从软件测试来看,软件开发有分析、开发和编码等几个阶段,每个阶段都可能产生错误,多数错是由于人员之间的交流不充分或存在误解等原因在接口上产生的(见图6-5)。
图6-5 软件测试与开发的关系
单元测试发现的错误主要是在编码阶段产生的错误;集成测试发现的错误主要是软件设计中的错误,也有可能发现需求说明书中的错误;确认测试主要发现分析阶段产生的错误。发现错误之后,常常需要回到编码、开发和分析等阶段,进行再编码、再开发和再分析。从这里可以看出一个严重的问题,即最早犯下的错误要到确认测试才能发现。如分析阶段的错误要到确认测试才能发现。因此在大多数情况下,要纠正系统测试发现的错误,涉及面将非常大。如果此时发现对用户的需求理解错误,要改动就需要付出极大的代价。
系统测试的最后一步通常为交付测试,其目的与系统测试一样。不同的是交付测试要由用户完成,用户常常要有计划地进行一系列测试,可能需要几个星期,甚至几个月。
▶6.2.2.3 回归测试
在软件测试过程中,在上述基本软件测试步骤的基础上,还有软件回归测试。软件回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。自动回归测试将大幅降低系统测试、维护升级等阶段的成本。
回归测试可遵循上述基本过程进行:
(1)识别出软件中被修改的部分。
(2)从原基线测试用例库中,排除所有不再适用的测试用例,确定那些对新的软件版本依然有效的测试用例,其结果是建立一个新的基线测试用例库。
(3)依据一定的策略从原基线测试用例库中选择测试用例被修改的软件。
(4)如果必要,生成新的测试用例集,用于测试原基线测试用例库中无法充分测试的软件部分。
(5)用新的测试用例集执行修改后的软件。
第(2)和第(3)步测试验证修改是否破坏了现有的功能,第(4)和第(5)步测试验证修改工作本身。
回归测试作为软件生命周期的一个组成部分,在整个软件测试过程中占有很大的工作量比重,软件开发的各个阶段都会进行多次回归测试。在渐进和快速迭代开发中,新版本的连续发布使回归测试进行得更加频繁,而在极端编程方法中,更是要求每天都进行若干次回归测试。因此,通过选择正确的回归测试策略来改进回归测试的效率和有效性是很有意义的。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。