首页 百科知识 软件测试阶段

软件测试阶段

时间:2022-10-09 百科知识 版权反馈
【摘要】:从宏观的角度讲,软件测试阶段一般可以划分为单元测试、集成测试、系统测试和验收测试等几个主要测试阶段。单元测试的测试对象是经过软件设计并编码的一个个程序模块。模块边界条件的测试是单元测试中最后也是最重要的一项测试任务,因为程序最容易在边界上出错。通常,单元测试在编码阶段进行。集成测试是在单元测试的基础上,按照系统设计要求把通过单元测试的单元模块逐步组装与测试,最后组装成一个完整的软件系统的测试过程。

6.2.4 软件测试阶段

宏观的角度讲,软件测试阶段一般可以划分为单元测试、集成测试、系统测试和验收测试等几个主要测试阶段。每一个测试阶段都应包含制订测试计划、设计测试用例、测试实施和测试结果的收集评估等。其中,测试计划应包括具体的测试步骤、工作量、进度安排和资源等。在测试的各个阶段,应适宜地选择黑盒测试和白盒测试方法,由开发人员和独立的测试小组单独、分别或共同完成测试任务,必要时还应有用户参加。下面着重讨论各个测试阶段的测试任务、测试步骤等内容。

一、单元测试

单元测试的测试对象是经过软件设计并编码的一个个程序模块。单元测试的主要依据是程序代码和详细设计文档。为了尽可能多地发现并纠正程序模块中的错误,单元测试多采用白盒测试技术,有时也结合黑盒测试技术。一般来说,单元测试可以并行进行。

1.单元测试的任务

单元测试的任务主要包括模块接口测试、模块局部数据结构的测试、模块中所有独立路径的测试、模块中各条错误处理路径的测试和模块边界条件的测试等。

(1)模块接口测试。模块接口测试是测试数据能否正确地流入、流出模块,它是实现其他单元测试任务的基础。模块接口测试的主要测试内容有:

①输入的实际参数与本模块的形式参数在个数、类型、顺序、量纲上是否一致。

②调用其他模块时所给实际参数与被调模块的形式参数在个数、类型、顺序、量纲上是否一致。

③调用预定义函数时所用参数的个数、类型、顺序、返回值的类型等是否正确。

④是否存在与当前入口点无关的参数引用。

⑤是否修改了只读型参数。

⑥各个模块对全局变量的定义和引用是否保持一致。

⑦是否把某些约束作为参数传递。

⑧如果模块内包括外部输入输出,还应测试文件属性是否正确、文件打开/关闭语句是否正确、格式说明与输入输出语句是否匹配、缓冲区大小与记录长度是否匹配、是否处理了文件尾、输出信息中是否存在文字错误等方面的内容。

(2)模块局部数据结构的测试。局部数据结构往往是错误的根源。因此,必须仔细设计测试用例对其进行全面检查,主要的测试内容有:

①不适合或不相容的类型说明。

②变量名不正确(拼写或截断错误等)。

③变量无初值或初始化、默认值有错。

④出现上溢出、下溢出、地址异常等。

(3)模块中所有独立路径的测试。单元测试的基本任务是保证每条语句、每条基路径、每个比较判断都至少执行一次。此时基路径测试、循环测试以及各种逻辑覆盖技术都是可以采用的有效测试技术。这种测试旨在找出因错误的计算、不正确的比较判断和不恰当的控制流等所造成的错误。其中:

①计算中常见的错误有:运算符优先级错误、混合运算类型匹配错误、变量初值错误、达不到精度、表达式不正确等。

②不正确的比较判断和不恰当的控制流常见的错误有:被比较的对象的类型不匹配、错误地使用逻辑运算符及其优先级、计算误差引起的判断错误、循环终止条件不合适、错误地修改了循环变量、迭代发散时不能退出循环等。

(4)模块中各条错误处理路径的测试。我们希望程序模块具有较强的容错能力,这就需要在设计时能预见各种出错条件,并预先设计好各种出错处理通路,以便在用户出现输入数据错误或操作错误时系统能给出恰当的提示而不使系统失效。出错处理路径测试主要测试的错误有:

①异常处理不当。

②在程序自定义的出错处理程序段运行之前系统已介入。

③显示的出错信息难以理解或未能提供足够的错误定位信息。

④显示的错误与实际发生的错误不符等。

(5)模块边界条件的测试。模块边界条件的测试是单元测试中最后也是最重要的一项测试任务,因为程序最容易在边界上出错。可以采用边界值分析技术针对边界值极其左右值设计测试用例,很有可能检测出新的错误。

2.单元测试的步骤

通常,单元测试在编码阶段进行。在源代码编制完成并经过编译检查和评审后,就可以开始进行单元测试。测试用例的设计应与评审工作相结合,根据测试计划和详细设计信息设计测试数据,并应给出对应的期望结果。

由于被测试的模块不是一个独立的程序,而是处于整个软件结构的某一层位置上,即被测模块在被其上层模块调用时才能运行,在运行时又要调用其直接的下层各模块。于是需要为被测模块编制一个驱动模块(Driver Module)和若干个桩模块(Stab Module)。

驱动模块的作用是用来模拟被测模块的上级调用模块,相当于被测模块的主程序,用它接收测试用例的测试数据,把这些测试数据传送给被测模块,接收被测模块的测试结果并输出。

桩模块(也称为存根模块)用来代替被测模块所调用的子模块。桩模块的作用是为被测模块提供所需要的信息,因此,桩模块越简单越好,不需要模拟子模块的所有功能。

例如,一个被测软件的结构图如图6.5所示,对其中的模块A进行单元测试的测试环境如图6.6所示。其中的驱动模块模拟调用模块M,桩模块l、2、3分别模拟被调用模块C、D、E。

img122

图6.5 软件层次结构图

img123

图6.6 模块A的单元测试环境

由上述可见,为了进行单元测试,一般需要编写测试程序(指驱动模块和桩模块),并且不把它们作为软件产品的一部分提交给用户。

有些模块用单元测试的方法不能进行充分的测试,为了减少开销,这些模块可以在集成测试的过程中完成详尽的测试。提高模块的内聚度可以简化单元测试过程。如果每个模块只完成一个功能,则所需测试用例的数目将显著减少,模块中的错误也更容易预测和发现。

二、集成测试

集成测试是在单元测试的基础上,按照系统设计要求把通过单元测试的单元模块逐步组装与测试,最后组装成一个完整的软件系统的测试过程。因此,集成测试又称为组装测试或综合测试。集成测试的主要依据是单元测试的单元及概要设计文档,旨在发现与接口有关的错误。这些错误包括:

①数据通过接口时会丢失。

②一个模块的功能对另一个模块产生了不利影响。

③几个子功能组合起来没有实现主功能。

④全局数据结构出现错误。

⑤误差的不断积累达到不能接受的程度等。

集成测试有两种集成方式,即非增量集成方式和增量集成方式。

1.非增量集成方式

非增量集成方式是将经过单元测试的所有模块一次性全部组装起来,然后进行整体测试,最后得到所要求的软件系统。这种集成方式容易出现混乱,因为开始可能遇到一大堆错误,而且出错的模块往往并不是错误隐藏的模块,加之模块众多,于是为每个错误定位非常困难。何况在改正一个错误时,还可能引入新的错误,新旧错误交织在一起,会使测试变得更加困难。因此,一般不应采用这种集成方式。

2.增量集成方式

增量集成方式是将经过单元测试的模块逐步组装成较大的系统,一边组装,一边进行测试,以便发现模块间与接口有关的问题。这种方式实际上可以同时完成单元测试和集成测试。根据组装方法的不同,可以分为自顶向下集成和自底向上集成两种方法。

(1)自顶向下集成。自顶向下集成方式是从主控模块开始,按照软件的控制层次结构,以深度优先或广度优先的策略,逐步把各个模块组装在一起。

自顶向下集成测试的具体步骤如下:

①对主控模块进行集成测试,所有被其直接调用的下属模块都用桩模块代替。

②依据所选用的集成策略(深度优先或广度优先)所规定的次序,每次只用一个实际模块替代一个对应的桩模块,并用新的桩模块代替新加入的模块,与已测模块或子系统构成新的子系统,进行测试。

③为确保新加入的模块未引入新的缺陷,每次都需要进行回归测试(即部分或全部执行以前做过的测试)。

④重复执行步骤②③,每重复一次,增加一个模块,直至所有模块都已集成到系统中。

如图6.7所示的被测软件系统结构图,如果采用深度优先策略,则以M1作为主控模块,集成测试步骤如下:

①首先测试M1模块,被调用模块M2、M3、M4分别用桩模块S2、S3、S4代替,然后对子系统M1、S2、S3、S4组成的子系统测试一遍。

②将模块M2加入其中,被调用模块M5、M6分别以桩模块S5、S6代替,于是对由M1、M2、S3、S4、S5、S6组成的子系统测试一遍。

③用M5代替S5,并用桩模块S8代替M8,对由M1、M2、M5、S3、S4、S8、S6组成的子系统再测试一遍。

④以此类推,以后依次集成的模块为M8、M6、M3、M7、M4。直至所有模块集成为完整的系统测试一遍。

一般来说,深度优先策略应首先把主控制路径上的模块集成起来,而主控制路径的选择应根据问题的特性来确定,有时可能带有一定的随意性。

而广度优先策略是沿控制层次结构水平地向下移动,按一层一层的顺序将模块一个个地集成起来。如图6.7所示的软件结构图,集成的顺序为M1、M2、M3、M4、M5、M6、M7、M8,在集成的过程中也需要桩模块的配合。

自顶向下集成的特点是不需要驱动模块,但需要大量的桩模块。其优点是能够尽早地验证程序的主要控制和判断机制,可以较早发现此类错误,从而减少以后的返工。其缺点是在测试较高层模块时,低层模块采用较简单的桩模块来代替,不能反映实际情况,测试可能不充分。

img124

图6.7 被测软件系统结构图

(2)自底向上集成。即从程序结构的最底层模块开始组装和测试。由于模块是按照自底向上的顺序进行组装的,当要测试某一给定层次的模块时,其所有下属模块都已组装测试完毕。因此,这种测试需要一定数量的驱动模块,而不需要桩模块。

自底向上集成测试的具体步骤如下:

①把低层模块组织成实现某个特定的软件子功能的模块群(Module Cluster)。

②为每一个模块群开发一个驱动模块,控制测试数据的输入和测试结果的输出。

③对每个模块群进行测试。

④去掉测试用的驱动模块,用较高层模块将几个模块群组成新的更大的模块群。

上述的②③④步骤重复执行,直至整个程序构造完毕。

例如,图6.8给出了自底向上的集成过程。首先,把软件结构图中的最底几层模块按照子功能划分为三个模块群,并为每一个模块群设计一个驱动模块进行测试。如模块群l、2、3的驱动模块分别为Dl、D2、D3。三个模块群测试完成后,去掉D1、D2两个驱动模块,用实际模块M2驱动模块群1和2,再为M2设计一个驱动模块D4,对由模块群l、2和M2组成的大模块群进行测试。同样,去掉D3,将M3和模块群3连起来组成较大的模块群,并设计一个驱动模块D5来驱动模块M3,对M3和模块群3组成的较大模块群进行测试,最后去掉D4和D5,直接用M1驱动M2和M3,于是构成一个完整的系统,进行最后的集成测试。

img125

图6.8 自底向上集成过程

自底向上集成的测试方法只需要设计驱动模块,不需要设计桩模块,测试用例的设计也相对简单,同时,由于涉及复杂算法和直接输入输出的模块最先得到组装和测试,可以在早期解决这些最容易出问题的部分。还有,自底向上集成可以实施多个模块并行测试。其缺点是只有程序最后一个模块(即主模块)加入后才具有整体形象,对其高层控制与判断进行测试的时间较晚,如果到测试的后期才发现整体存在较严重问题,就不得不进行较大的返工,此时的代价将是巨大的。

(3)混合式测试及重点测试。根据前面对自顶向下和自底向上两种集成测试方法的介绍,我们知道两种测试方法的优缺点刚好相反,因此,可以将两种测试策略结合起来使用,即对于上层模块采用自顶向下的方法,而对于下层模块采用自底向上的方法。这样不仅可以大大减少开发驱动模块和桩模块的数量,还可以充分发挥各自的优点。这种方法又称为三明治集成方法。

此外,在集成测试过程中应对关键模块进行重点测试。关键模块是指具有如下一个或多个特征的模块:

①对应多条需求。

②具有高层控制功能。

③复杂、易出错。

④有特殊性能要求。

对关键模块应尽早测试,并应进行反复的回归测试。

三、确认测试

确认测试又称有效性测试,任务是验证软件的功能和性能及其他特性是否与用户的要求一致。对软件的功能和性能要求在软件需求规格说明书中已经明确规定,它包含的信息就是软件确认测试的基础。通过集成测试之后,软件已完全组装起来,接口方面的错误也已排除,确认测试应检查软件能否按合同要求进行工作,即是否满足软件需求说明书中的确认标准。

1.确认测试标准

实现软件确认要通过一系列黑盒测试。确认测试同样需要制订测试计划和过程,测试计划应规定测试的种类和测试进度,测试过程则定义一些特殊的测试用例,旨在说明软件与需求是否一致。无论是计划还是过程,都应该着重考虑软件是否满足合同规定的所有功能和性能,文档资料是否完整、准确,人机界面和其他方面(例如,可移植性、兼容性、错误恢复能力和可维护性等)是否令用户满意。

确认测试的结果有两种可能:一种是功能和性能指标满足软件需求说明的要求,用户可以接受;另一种是软件不满足软件需求说明的要求,用户无法接受。项目进行到这个阶段才发现严重错误和偏差,一般很难在预定的工期内改正,因此必须与用户协商,寻求一个妥善解决问题的方法。

2.配置复审

确认测试的另一个重要环节是配置复审。复审的目的在于保证软件配置齐全、分类有序,两者要一致,并且包括软件维护所必需的细节。

3.α测试和β测试

事实上,软件开发人员不可能完全预见用户实际使用程序的情况。例如,用户可能错误地理解命令,或提供一些奇怪的数据组合,亦可能对设计者已认明了的输出信息迷惑不解,等等。因此,软件是否真正满足最终用户的要求,应由用户进行一系列“验收测试”。这种测试既可以是非正式的测试,也可以有计划、有系统地测试。有时,这个测试过程长达数周甚至数月,不断暴露错误,导致开发延期。一个软件产品拥有众多用户,不可能由每个用户验收,此时多采用被称为α、β测试的过程,以期待发现那些似乎只有最终用户才能发现的问题。

α测试是指软件开发公司组织内部人员模拟各类用户对即将面市的软件产品(称为α版本)进行测试,试图发现错误并修正。α测试的关键在于尽可能逼真地模拟实际运行环境和用户对软件产品的操作并尽最大努力涵盖所有可能的用户操作方式。

经过α测试调整的软件产品称为β版本。紧随其后的β测试是指软件开发公司组织各方面的典型用户在日常工作中实际使用β版本,并要求用户报告异常情况,提出批评意见,然后软件开发公司再对β版本进行改错和完善。

四、系统测试

系统测试是将通过确认测试的软件,作为整个基于计算机系统的一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其他系统元素结合在一起,在实际运行(使用)环境下,对计算机系统进行一系列的组装测试和确认测试。在系统测试实施之前,软件工程师应完成以下工作:为测试软件系统的输入信息设计出错处理通路;设计测试用例,模拟错误数据和软件界面可能发生的错误,记录测试结果,为系统测试提供经验和帮助;参与系统测试的规划和设计,保证软件测试的合理性。

系统测试实质上是由一系列不同测试组成的,其主要目的是充分运行系统,验证系统各个部件是否都能正常工作并完成所分配的功能。以下,我们将讨论用于系统的几种软件系统测试类型。

1.恢复测试

恢复测试主要检查系统的容错能力。当系统出错时,能否在指定的时间间隔内修正错误并重新启动系统。恢复测试首先要采用不同的方式强迫系统出现故障,然后验证系统是否能尽快恢复。如果恢复是自动的(由系统自身完成),则重新初始化、检测点设置、数据恢复以及重新启动等都是对其正确性的评价。若恢复需人工干预,则需估算出修复的平均时间,确定其是否在可接受的限制范围以内。

2.安全性测试

系统的安全性测试是要检验在系统中已存在的系统安全性措施、保密性措施是否发挥作用,有无漏洞。在安全性测试过程中,测试人员应扮演非法入侵者,采用各种办法试图突破防线。如,想方设法截取或破译口令;专门定做软件破坏系统的保护机制;故意导致系统失败,企图趁系统恢复之机非法进入;试图通过浏览非保密数据,推导所需信息等等。系统安全设计的准则是使非法入侵的代价超过被保护信息的价值。这样,非法入侵者就会无利可图。

3.强度测试

强度测试是要检查在系统运行环境不正常到发生故障的时间内,系统可以运行到何种程度的测试。强度测试是在要求一个非正常数量、频率或容量资源方式下运行一个系统。如,当平均速度有一种或两种时,可以设计每秒产生十个中断的特殊测试;定量地增长数据输入率,检查输入子功能的反应能力;运行需要最大内存或其他资源的测试用例;运行可能导致虚拟操作系统崩溃或磁盘剧烈抖动的测试用例等。

4.性能测试

性能测试就是测试软件在被组装进系统的环境下运行时的性能。性能测试应覆盖测试过程的每一步。即使在单元层,单个模块的性能也可以通过白盒测试来评价,而不是等到所有系统元素全部组装以后,再确认系统的真正性能。性能测试有时是与强度测试联系在一起的,常常需要硬件和软件的测试设备。

五、验收测试

验收测试是软件开发结束后,软件产品投入实际应用以前进行的最后一次质量检验活动,是以用户为主,软件开发人员和质量保证人员也应参加的测试。它要回答开发的软件产品是否符合预期的各项要求,以及用户能否接受的问题。由于不只是检验软件某个方面的质量,而是要进行全面的质量检验,并且要确定软件是否合格,因此验收测试是一项严格的正式测试活动。需要根据事先制订的计划,进行软件配置评审、功能测试、性能测试等多方面检测。

用户验收测试可以分为两个大的部分:软件配置审核和可执行程序测试。其大致顺序可分为:文档审核、源代码审核、配置脚本审核、测试程序或脚本审核、可执行程序测试。

要注意的是,在开发方将软件提交用户方进行验收测试之前,必须保证开发方本身已经对软件的各方面进行了足够的正式测试(当然,这里的“足够”,本身是很难准确定量的)。

用户验收测试的每一个相对独立的部分,都应该有目标(本步骤的目的)、启动标准(着手本步骤必须满足的条件)、活动(构成本步骤的具体活动)、完成标准(完成本步骤要满足的条件)和度量(应该收集的产品与过程数据)。在实际验收测试过程中,收集度量数据,不是一件容易的事情。

1.软件配置审核

对于一个外包的软件项目而言,软件承包方通常要提供如下相关的软件配置内容:

(1)可执行程序、源程序、配置脚本、测试程序或脚本。

(2)主要的开发类文档:《需求分析说明书》《概要设计说明书》《详细设计说明书》《数据库设计说明书》《测试计划》《测试报告》《程序维护手册》《程序员开发手册》《用户操作手册》《项目总结报告》。

(3)主要的管理类文档:《项目计划书》《质量控制计划》《配置管理计划》《用户培训计划》《质量总结报告》《评审报告》《会议记录》《开发进度月报》。

需要注意的是,在开发类文档中,容易被忽视的文档有《程序维护手册》和《程序员开发手册》。《程序维护手册》的主要内容包括:系统说明(包括程序说明)、操作环境、维护过程、源代码清单等,编写目的是为将来的维护、修改和再次开发工作提供有用的技术信息。《程序员开发手册》的主要内容包括:系统目标、开发环境使用说明、测试环境使用说明、编码规范及相应的流程等,实际上就是程序员的培训手册。

不同大小的项目,都必须具备上述的文档内容,只是可以根据实际情况进行重新组织。对上述的提交物,最好在合同中规定阶段提交的时间,以免发生纠纷。

通常,正式的审核过程分为5个步骤:计划、预备会议(可选)、准备阶段、审核会议和问题追踪。预备会议是对审核内容进行介绍并讨论。准备阶段就是各责任人事先审核并记录发现的问题。审核会议是最终确定工作产品中包含的错误和缺陷。

审核要达到的基本目标是:根据共同制定的审核表,尽可能地发现被审核内容中存在的问题,并最终得到解决。在根据相应的审核表进行文档审核和源代码审核时,还要注意文档与源代码的一致性。

在实际的验收测试执行过程中,常常会发现文档审核是最难的工作,一方面由于市场需求等方面的压力使这项工作常常被弱化或推迟,造成持续时间变长,加大文档审核的难度;另一方面,文档审核中不易把握的地方非常多,每个项目都有一些特别的地方,而且也很难找到可用的参考资料。

2.可执行程序的测试

在文档审核、源代码审核、配置脚本审核、测试程序或脚本审核都顺利完成后,就可以进行验收测试的最后一个步骤——可执行程序的测试,它包括功能、性能等方面的测试,每种测试也都包括目标、启动标准、活动、完成标准和度量等五部分。

要注意的是不能直接使用开发方提供的可执行程序用于测试,而要按照开发方提供的编译步骤,从源代码重新生成可执行程序。

在真正进行用户验收测试之前一般应该已经完成了以下工作(也可以根据实际情况有选择地采用或增加):

(1)软件开发已经完成,并全部解决了已知的软件缺陷。

(2)验收测试计划已经过评审并批准,并且置于文档控制之下。

(3)对软件需求说明书的审查已经完成。

(4)对概要设计、详细设计的审查已经完成。

(5)对所有关键模块的代码审查已经完成。

(6)对单元、集成、系统测试计划和报告的审查已经完成。

(7)所有的测试脚本已完成,并至少执行过一次,且通过评审。

(8)使用配置管理工具且代码置于配置控制之下。

(9)软件问题处理流程已经就绪。

(10)已经制定、评审并批准验收测试完成标准。

具体的测试内容通常可以包括:安装(升级)、启动与关机、功能测试(用例、重要算法、边界、时序、反例、错误处理)、性能测试(正常的负载、容量变化)、压力测试(临界的负载、容量变化)、配置测试、平台测试、安全性测试、恢复测试(在出现断电、硬件故障或切换、网络故障等情况时,系统是否能够正常运行)、可靠性测试等。

性能测试和压力测试一般情况下是在一起进行,通常还需要辅助工具的支持。在进行性能测试和压力测试时,测试范围必须限定在那些使用频度高和时间要求苛刻的软件功能上集中。由于开发方已经事先进行过性能测试和压力测试,因此可以直接使用开发方的辅助工具,也可以通过购买或自己开发来获得辅助工具。具体的测试方法可以参考相关的软件测试书籍。

如果执行了所有的测试案例、测试程序或脚本,用户验收测试中发现的所有软件问题都已解决,而且所有的软件配置均已更新和审核,可以反映出软件在用户验收测试中所发生的变化,用户验收测试就完成了。验收测试工作流程图见图6.9所示。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈