第2章 软件测试基础
2.1 软件测试与软件质量
一、软件测试的定义
测试的含义为“以检验产品是否满足需求为目标”,“软件测试”的经典定义为在规定条件下对程序进行操作,以发现错误,对软件质量进行评估。
软件由文档、数据以及程序组成,软件测试为对软件形成过程的文档、数据以及程序进行测试,而不仅仅对程序进行测试。做好软件需求和设计阶段的测试工作非常重要。
随着人们对软件工程化的重视以及软件规模的日益扩大,软件分析、设计的作用越来越突出,做好软件需求和设计阶段的测试工作就显得非常重要。
二、软件质量的定义
(1)1991年,软件产品质量评价国际标准ISO9126将“软件质量”定义为:软件满足规定或潜在用户需求特性的总和。
(2)1999年,软件“产品评价”国际标准ISO14598经典的“软件质量”定义是:软件特性的总和,软件满足规定或潜在用户需求的能力。
(3)一般对“质量”的理解是一个实体的“属性”, “属性”是内在特性,内在特性好,不一定能胜任和完成好用户的任务,软件质量也是关于软件特性具备“能力”的体现。
(4)2001年,软件“产品质量”国际标准ISO9126定义的软件质量包括“内部质量”“外部质量”和“使用质量”三部分,即“软件满足规定或潜在用户需求的能力”要从软件的内部、外部和使用中的表现来衡量。
三、软件测试与质量保证的区别
软件质量保证和软件测试是软件质量工程的两个不同层面的工作,测试只是质量保证工作中的一个环节。
1.质量保证(QA)
质量保证的重要工作通过预防、检查与改进来保证软件质量。
(1)QA采用“全面质量管理”和“过程改进”的原理开展质量保证工作。关注软件质量的检查与测量。虽然在QA的活动中有测试活动,但所关注的是软件质量的检查与测量。
(2)QA的工作是软件生命周期的管理以及验证软件是否满足规定的质量和用户的需求,故主要着眼于软件开发活动中的过程、步骤和产物,而不是对软件进行剖析找出问题或评估。
2.软件测试
测试虽然也与开发过程紧密相关,但关心的不是过程的活动,而是对过程的产物以及开发出的软件进行剖析。
(1)测试人员要“执行”软件,对过程中的产物——开发文档和源代码进行走查,运行软件,以找出问题,报告质量。
(2)测试人员必须假设软件存在潜在的问题,测试中所作的操作是为了找出更多的问题,而不仅仅是为了验证每一件事是正确的。对测试中发现的问题的分析、追踪与回归测试也是软件测试中的重要工作,故软件测试是保证软件质量的一个重要环节。
2.2 软件测试目的
一、背景
1.Grenford J.Myers就软件测试目的提出的观点
(1)测试是程序的执行过程,目的在于发现错误;
(2)一个好的测试用例在于能发现至今未发现的错误;
(3)一个成功的测试是发现了至今未发现的错误的测试。
2.Bill Hetzel就软件测试目的提出的观点
软件测试不仅是为了发现软件缺陷与错误,且也是对软件质量进行度量和评估,以提高软件质量。
二、测试的目的
(1)以最少的人力、物力和时间找出软件中潜在的各种错误和缺陷,修正各种错误和缺陷提高软件质量,回避软件发布后由于软件潜在的缺陷和错误造成的隐患所带来的商业风险。
(2)测试是以评价一个程序或者系统属性为目标的活动,是对软件质量的度量与评估,以验证软件的质量满足用户的需求的程度,为用户选择与接受软件提供有力依据。
(3)通过分析错误产生的原因可以帮助发现当前开发工作所采用的软件过程的缺陷,以便进行软件过程改进。同时,通过对测试结果的分析整理,还可以修正软件开发规则,并为软件可靠性分析提供依据。
(4)通过最终的验收测试,可以证明软件满足用户需求,树立人们使用软件的信心。
2.3 软件测试原则
一、所有的软件测试都应追溯到用户需求
由于软件的目的是使用户完成预定的任务,并满足用户的需求,而软件测试所揭示的缺陷和错误使软件达不到用户的目标,满足不了用户需求。
二、应当把“尽早地和不断地进行软件测试”作为软件测试者的座右铭
由于软件的复杂性和抽象性,在软件生命周期各个阶段都可能产生错误,所以应将软件测试贯穿到软件开发的各个阶段中。在软件开发的需求分析和设计阶段就应开始测试工作,编写相应的测试文档。同时,坚持在软件开发的各个阶段进行技术评审与验证,尽早发现和预防开发过程中的错误,杜绝某些缺陷和隐患,提高软件质量。只要测试在生命周期中进行得足够早,就能提高被测软件的质量,这就是预防性测试的基本原则。
三、完全测试是不可能的,测试需要终止
想要进行完全的测试,在有限的时间和资源条件下,找出所有的软件缺陷和错误,使软件趋于完美,是不可能的。主要有以下三个原因:
(1)输入量太大;
(2)输出结果太多;
(3)路径组合太多。
一个适度规模的程序,其路径组合近似天文数字,对于每种可能的路径都执行一次穷举测试是不可能的。且测试是有成本的,越是测试后期,为发现错误所付出的代价会越大,因此要根据测试错误概率以及软件可靠性要求,确定最佳停止测试时间,不能无限测试下去。
四、测试无法显示软件潜在的缺陷
进行测试可查找并报告已发现的软件缺陷和错误,但不保证软件缺陷和错误全部被找到,即测试只能证明软件存在错误而不能证明软件没有错误。
五、充分注意测试中的群集现象
经验表明,测试后程序中残存的错误数目与该程序中已发现的错误数目或检错率成正比。根据该规律,对错误群集的程序段进行重点测试,以提高测试投资的效益。如果发现某一程序模块比其他程序模块有更多的错误倾向,应当花费较多的时间和代价测试该程序模块。
六、程序员应避免检查自己的程序
由于思维定势,难于发现自己的错误。故为达到测试的目的,应由客观、公正、严格的独立测试部门或者独立的第三方测试机构来进行测试。
七、尽量避免测试的随意性
应该从工程的角度去理解软件测试,其是有组织、有计划、有步骤的活动。
2.4 软件测试对象
一、概述
在整个软件生命周期中,各阶段有不同的测试对象,形成了不同开发阶段的不同类型的测试。需求分析、概要设计、详细设计以及程序编码等各阶段所得到的文档,包括需求规格说明、概要设计规格说明、详细设计规格说明以及源程序,都应成为“软件测试”的对象。
二、验证和确认
对程序编写而言,它的许多错误是“先天的”。事实上,到程序的测试为止,软件开发工作已经经历了许多环节,每个环节都可能发生问题。
为了把握各个环节的正确性,人们需要进行各种验证和确认。
(1)验证(verification)
保证软件正确实现特定功能的一系列活动和过程,目的是保证软件生命周期中的每一个阶段的成果满足上个阶段所设定的目标。
(2)确认(validation)
保证软件满足用户需求的一系列的活动和过程,目的是在软件开发完成后保证软件与用户需求相符合。
验证与确认都属于软件测试,包括对软件分析、设计以及程序的验证和确认。
2.5 软件测试分类
一、按照开发阶段划分
1.单元测试(模块测试)
单元测试是软件编码约束,针对软件设计的最小单位——程序模块进行正确性检验的测试工作。其目的在于检查每个程序单元能否正确实现详细设计说明中的模块功能、性能、接口和设计约束等要求,发现各模块内部可能存在的各种错误。单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。
2.集成测试(组装测试)
集成测试是模块集成后,对集成在一起的模块组件(可称为“部件”)进行的测试工作。它通常在单元测试的基础上,将所有的程序模块进行有序的、递增的测试。
集成测试是检验程序单元或部件的接口关系,逐步集成为符合概要设计要求的程序部件或整个系统。软件集成的过程是个持续的过程,在不断的集成过程中,功能集成的稳定性是真正的挑战。在各版本提交时,都需要进行冒烟测试,也称版本测试或者提交测试,即对程序主要功能进行验证。
3.确认测试
确认测试是集成测试后,检测与证实软件是否满足软件需求说明书中规定的要求。通过检验和提供客观证据,证实软件是否满足特定预期用途的需求。
4.系统测试
系统测试是为验证和确认系统是否达到其原始目标,而对集成的硬件和软件系统进行的测试。系统测试是在真实或模拟系统运行的环境下,检查完整的程序系统能否和系统(包括硬件、外设、网络和系统软件、支持平台等)正确配置、连接,满足用户需求。
5.验收测试
按照项目任务书或合同、供需双方约定的验收依据文档进行的对整个系统的测试与评审,决定是否接收系统。
二、按照测试实施组织划分
1.开发方测试(验证测试或α测试)
开发方通过检测和提供客观证据,证实软件的实现是否满足规定的需求。验证测试是在软件开发环境下,由开发者检测与证实软件的实现是否满足软件设计说明或软件需求说明的要求。主要是指在软件开发完成以后,开发方对要提交的软件进行全面的自我检查与验证,可和软件的“系统测试”一并进行。
2.用户测试
在用户的应用环境下,用户通过运行和使用软件,检测与核实软件实现是否符合自己预期的要求。通常的用户测试是指用户的使用性测试。
β测试通常被看成是一种“用户测试”。β测试主要是把软件产品有计划地免费分发到目标市场,让用户大量使用,并评价、检查软件。通过用户各种方式的大量使用,来发现软件存在的问题与错误,把信息反馈给开发者修改。β测试中厂商获取的信息,可有助于软件产品的成功发布。
3.第三方测试(独立测试)
第三方测试是介于软件开发方和用户方之间的测试组织的测试,软件质量工程强调开展独立验证和确认,也就是由在技术、管理和财务上与开发方和用户方相对独立的组织进行的软件测试。通常是在模拟用户真实应用环境下,进行软件确认测试。
三、按照测试技术划分
1.可划分为静态测试和动态测试
(1)静态测试(静态分析技术)
静态测试是指不运行程序,通过人工对程序和文档进行分析与检查。静态测试实际上是对软件中的需求说明书、设计说明书、程序源代码等进行非运行的检查,它主要包括:走查、符号执行、需求确认等。
(2)动态测试
动态测试是指通过人工或使用工具运行程序进行检查,分析程序的执行状态和程序的外部表现。
2.可划分为白盒测试、黑盒测试和灰盒测试
(1)白盒测试(结构测试)
通过对程序内部结构的分析、检测来寻找问题。白盒测试要求清楚了解程序结构和处理过程,检查是否所有的结构及路径都是正确的,检查软件内部动作是否按照设计说明的规定正常进行。
(2)黑盒测试
通过软件的外部表现来发现其缺陷和错误。黑盒测试法是完全不考虑程序内部结构和处理过程,在程序界面处进行测试,只是检查程序是否按照需求规格说明书的规定正常实现。
(3)灰盒测试
介于白盒测试与黑盒测试之间的测试。灰盒测试关注输出对于输入的正确性和内部表现,这种关注只是通过一些表征性的现象、事件、标志来判断内部的运行状态。它结合了白盒测试和黑盒测试的要素,考虑了用户端、特定的系统知识和操作环境,在系统组件的协同性环境中评价应用软件的设计。
开发文档和源程序可以应用单元测试中走查的方法;单元测试可应用白盒测试的方法;集成测试应用近似灰盒测试的方法;而系统测试和确认测试应用黑盒测试的方法。
2.6 软件测试过程模型
一、V模型
软件测试是与软件开发紧密相关的一系列有计划的系统性的活动,也需要一些测试模型去指导实践,在这些测试模型中也都把开发过程进行了很好的总结,体现了测试与开发的融合。
1.测试模型简介
V模型是最具有代表意义的测试模型,如图2-1所示。旨在改进软件开发的效率和效果。
图2-1 软件测试V模型
V模型是软件开发瀑布模型的变种,反映了测试活动与分析和设计的关系,从左到右,描述了基本的开发过程和测试行为,非常明确地标明了测试过程中存在的不同级别,并且清楚地描述了这些测试阶段和开发过程期间各阶段的对应关系。如模型图(图2-1)所示,图中的箭头代表了时间方向,左边下降的是开发过程各阶段,右边上升的是各测试过程的各个阶段。
2.V模型的软件测试策略
(1)低层测试:为了源代码的正确性;
(2)高层测试:为了使整个系统满足用户的需求。
3.内容
(1)单元和集成测试是验证程序设计中,开发人员和测试组应检测程序的执行是否满足软件设计的要求。
(2)系统测试应验证系统设计,检测系统功能、性能的质量是否达到系统设计指标。
(3)由测试人员和用户进行软件的确认测试和验收测试,追溯软件需求说明书进行测试,以确定软件的实现是否满足用户需求或合同的要求。
4.局限性
仅仅把测试过程作为在需求分析、概要设计、详细设计及编码之后的一个阶段。容易使人理解为测试是软件开发的最后的一个阶段,主要是针对程序进行测试寻找错误,而需求分析阶段隐藏的问题一直到后期的验收测试才被发现。
二、W模型
1.建立
在V模型中增加软件各开发阶段应同步进行的测试,演化为一种w模型。因为实际上开发是“V”,测试也是与此相并行的“V”。基于“尽早地和不断地进行软件测试”的原则,在软件的需求和设计阶段的测试活动应遵循IEEE std1012-1998《软件验证和确认(V&V)》的原则。一个基于V&V原理的w模型示意图如图2-2所示。
图2-2 软件测试W模型
2.特点
(1)W模型可以说是V模型自然而然的发展,它强调:测试伴随着整个软件开发周期,而且测试的对象不仅仅是程序,需求、功能和设计同样要测试。因此只要相应的开发活动完成,就可以开始执行测试,即测试与开发是同步进行的,这样有利于尽早发现问题。
(2)如果测试文档能尽早提交,则有更多的检查和检阅的时间,这些文档还可用于评估开发文档。另外,测试者可以在项目中尽可能早地面对规格说明书的挑战。这意味着测试不仅是评定软件质量,测试还可尽可能早地找出缺陷所在,从而帮助改进项目内部的质量。参与前期工作的测试者可以预先估计问题和难度,显著地减少总体测试时间,加快项目进度。
(3)根据W模型的要求,一有文档提供,就要及时确定测试条件,并编写测试用例,这些工作对测试的各级别都有意义。当需求被提交后,就需要确定高级别的测试用例来测试这些需求。当概要设计编写完成后,就需要确定测试条件来查找该阶段的设计缺陷。
3.局限性
同V模型一样,W模型把软件的开发视为需求、设计、编码等一系列串行的活动。故软件开发和测试保持一种线性的前后关系,需要有严格的指令表示上阶段完全结束,才可正式开始下个阶段。故无法支持迭代、自发性以及变更调整。对于当前很多文档需要事后补充,或者根本没有文档的做法下,开发人员和测试人员都面临同样的困惑。
三、H模型
1.建立
因为相应的测试之间也不存在严格的次序关系,各层次之间的测试也存在反复触发、迭代和增量关系。另外,V模型和W模型都没有很好地体现测试流程的完整性。针对这一问题提出了H模型的概念。
H模型将测试活动完全独立出来,形成一个完全独立的流程,将测试准备活动和测试执行活动清晰地体现出来。H模型的简单示意图如图2-3所示。
图2-3 软件测试H模型
该示意图仅演示了在整个生产周期中某个层次上的一次测试“微循环”。图中的其他流程可以是任意开发流程。即只要测试条件成熟了,测试准备活动完成了,测试执行活动就可以(或者说需要)进行。
2.内容
H模型揭示了:
(1)软件测试不仅仅指测试的执行,还包括很多其他的活动。
(2)软件测试是个独立的流程,贯穿产品整个生命周期,与其他流程并发地进行。
(3)软件测试要尽早准备,尽早执行。
(4)软件测试是根据被测物的不同而分层次进行的。不同层次的测试活动可以是按照某个次序先后进行的,但也可能是反复的。
四、其他模型
1.X模型
基本思想是由Mafick提出的,其目标是弥补V模型的一些缺陷。软件测试的X模型如图2-4所示。
图2-4 软件测试x模型
X模型左边描述的是针对单独程序片段所进行的相互分离的编码和测试,此后,将进行频繁的交接,通过集成最终合成为可执行的程序。该点在图的右上方得以体现,而且这些可执行程序还需要进行测试,已通过集成测试的成品可以进行封版并提交给用户,也可作为更大规模和范围内集成的一部分。X模型还定位了探索性测试,如图2-4中右下方所示。这是不进行事先计划的特殊类型的测试,能帮助有经验的测试人员发现更多的软件错误。
2.前置测试模型
由Robin F.Goldsmith等人提出,它是一个将测试和开发紧密结合的模型,该模型提供了轻松的方式,可以使项目加快速度。前置测试模型如图2-5所示。
图2-5 前置测试模型
该模型体现了以下要点:
(1)开发和测试相结合
前置测试模型将开发和测试的生命周期整合在一起,标识了项目生命周期从开始到结束之间的关键行为。并且标识了这些行为在项目周期中的价值。如果其中有些行为没有得到很好得执行,则项目成功的可能性会有所降低。如果有业务需求,则系统开发过程将更有效率。通常认为在没有业务需求的情况下进行开发和测试是不可能的。而且,业务需求最好在设计和开发之前就被正确定义。
(2)对每个交付内容进行测试
每个交付的开发结果都必须通过一定的方式进行测试。源程序代码并不是唯一需要测试的内容。图中的椭圆框表示了其他一些要测试的对象,包括可行性报告、业务需求说明,以及系统设计文档等。在V模型基础上有所扩展,变得更为明确。
(3)在设计阶段进行测试计划和测试设计
设计阶段是做测试计划和测试设计的最好时机。很多组织要么根本不做测试计划和测试设计,要么在即将开始执行测试之前飞快地完成测试计划和测试设计。在这种情况下,测试只是验证程序的正确性,而不是验证整个系统本该实现的东西。
(4)测试和开发结合在一起
前置测试将测试执行和开发结合在一起,并在开发阶段以编码——测试——编码——测试的方式来体现。即程序片段一旦被编写完成,就会立即进行测试。通常先进行的测试是单元测试,因为开发人员认为通过测试来发现错误是最经济的方式。一个程序片段也需要相关的集成测试,甚至有时还需要一些特殊测试。对于特定的程序片段,其测试的顺序可以按照V模型的规定,但其中还会交织一些程序片段的开发,而不是按阶段完全地隔离。
(5)让验收测试和技术测试保持相互独立
前置测试模型提倡验收测试和技术测试沿循两条不同的路线来进行,每条路线分别验证系统是否能够如预期设想的那样进行正常工作。当单独设计好的验收测试完成了系统的验证时,即可确信这是正确的系统。验收测试既可以在实施阶段的第一步来执行,也可在开发阶段的最后一步执行。
五、测试模型的使用
这些模型对指导测试工作的进行具有重要的意义,在实际的工作中,要灵活地运用各种模型的优点,在W模型的框架下,运用H模型的思想进行独立地测试,并同时将测试和开发紧密结合,寻找恰当的就绪点开始测试并反复迭代测试,最终保证按期完成预定的目标。
2.7 软件生命周期测试策略
一、软件开发与软件测试
1.概述
以V模型为例,重点强调软件生命周期中程序开发部分需要经历的若干个测试级别。软件开发过程是一个自顶向下,逐步细化的过程。
(1)在软件计划阶段定义了软件的作用域;
(2)进行软件需求分析,制定软件数据域、功能和性能需求、约束及一些有效性准则;
(3)开始软件开发,进行软件设计,把设计用某种程序设计语言转换成程序代码;
(4)测试过程是依照相反的顺序安排自底向上,逐步集成的过程。低一级测试为上一级测试准备条件。当然不排除两者平行地进行测试。
2.软件测试与软件开发过程的关系
如图2-6所示,首先对每一个程序模块进行单元测试,消除程序模块内部在逻辑上和功能上的错误和缺陷。再对照软件设计进行集成测试,检测和排除子系统(或系统)结构上的错误。随后再对照需求,进行确认测试。最后从系统整体出发,运行系统,看是否满足要求。
图2-6 软件测试与软件开发过程的关系
二、软件测试策略
1.测试过程
如图2-7所示,软件测试经历的4个步骤。
图2-7 软件测试的过程
(1)单元测试
集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。
(2)集成测试(组装测试)
把已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。为此,在将一个个实施了单元测试并确保无误的程序模块组装成软件系统的过程中,对正确性和程序结构等方面进行检查。
(3)确认测试
要检查已实现的软件是否满足需求规格说明中确定的各种需求,以及软件配置是否完全、正确。
(4)系统测试
把已经经过确认的软件纳入实际运行环境中,与其他系统成分组合在一起进行测试。严格地说,系统测试已超出了软件工程的范围。
2.测试信息流
测试信息流如图2-8所示。
图2-8 测试信息流
(1)测试过程中需要的输入
①软件配置
软件配置包括软件需求规格说明、软件设计规格说明、源代码等。
②测试配置
测试配置包括测试计划、测试用例、测试驱动程序等。实际上,在整个软件工程中,测试配置只是软件配置的一个子集。
③测试工具
为提高软件测试效率,使用测试工具支持测试工作,作用就是为测试的实施提供某种服务,以减轻测试任务中的手工劳动。
(2)测试之后的工作
要对所有测试结果进行分析,即将实测的结果与预期的结果进行比较。若发现出错数据,即软件有错误,需要开始排错(调试)。即对已发现的错误进行错误定位和确定出错性质,并改正该错误,且修改相关的文档。修正后的文档一般要经过再次测试,直到通过测试为止。
(3)排错的过程
测试过程中最不可预知的部分,即使是一个与预期结果只相差0.01%的错误,也可能需要花上一个小时、一天、甚至一个月的时间去查找原因并改正错误。也正是因为排错中的这种固有的不确定性,所以很难确定可靠的测试进度。
(4)说明
通过收集和分析测试结果数据,开始针对软件建立可靠性模型。
①如果经常出现需要修改设计的严重错误,那么软件质量和可靠性就值得怀疑,同时也表明需要进一步测试。
②如果与此相反,软件功能能够正确完成,出现的错误易于修改,则可断定:或者是软件的质量和可靠性达到可以接受的程度,或者是所作的测试不足以发现严重的错误。
③如果测试发现不了错误,则几乎可肯定,测试配置考虑得不够细致充分,错误仍然潜伏在软件中。这些错误最终会由用户在使用过程中发现,并在维护时由开发者去改正。但那时改正错误的费用将比在开发阶段改正错误的费用要高出40~60倍。
3.分析设计阶段
(1)需求说明书评测
①概述
在需求分析阶段评测的工作重点是与承建单位的分析人员、设计人员一起对需求说明书进行审查,并协调业主单位完成需求说明书的评审确认。
②编制良好的需求说明书的原则
1979年由Balzer和Goldman提出了作出良好规格说明的8条原则:
a.功能与实现分离,即描述要“做什么”而不是“怎样实现”;
b.要求使用面向处理的规格说明语言,讨论来自环境的各种刺激可能导致系统做出什么样的功能性反应,来定义一个行为模型,从而得到“做什么”的规格说明;
c.如果目标软件只是一大系统中的一个元素,则整个大系统也包括在规格说明的描述之中。描述该目标软件与系统的其他系统元素交互的方式;
d.规格说明必须包括系统运行的环境;
e.系统规格说明必须是一个认识的模型,而不是设计或实现的模型;
f.规格说明必须是可操作的。规格说明必须是充分完全和形式的,以便能够利用它决定对于任意给定的测试用例,已提出的实现方案是否都能满足规格说明;
g.规格说明必须容许不完备性并允许扩充;
h.规格说明必须局部化和松散的耦合。包括的信息必须局部化,故当信息被修改时,只要修改某个单个的段落。且规格说明应被松散地构造(即耦合),以便能够很容易地加入和删去一些段落。
③需求说明书的框架
需求说明书的框架如表2-1所示。
表2-1 需求说明书的框架
④需求说明书评测内容
需求说明书评测作为需求分析阶段工作的复查手段,应该对功能的正确性、完整性和清晰性,以及其他需求给予评测。评测的主要内容如下:
a.系统定义的目标是否与用户的要求一致;
b.系统需求分析阶段提供的文档资料是否齐全;
c.文档中的所有描述是否完整、清晰,准确地反映用户要求;
d.与所有其他系统成份的重要接口是否都已经描述;
e.被开发项目的数据流与数据结构是否足够、确定;
f.所有图表是否清楚,在不补充说明时能否理解;
g.主要功能是否已包括在规定的软件范围之内,是否都已充分说明;
h.软件的行为和其必须处理的信息、必须完成的功能是否一致;
i.设计的约束条件或限制条件是否符合实际;
j.是否考虑了开发的技术风险;
k.是否考虑过软件需求的其他方案;
l.是否考虑过将来可能会提出的软件需求;
m.是否详细制定了检验标准,能否对系统定义是否成功进行确认;
n.有没有遗漏、重复或不一致的地方;
o.用户是否审查了初步的用户手册或原型;
p.项目开发计划中的估算是否受到了影响。
⑤需求说明书评测规范
根据上述讨论的评测内容,可以制定需求说明书评测规范,如表2-2所示。填表说明:Y-是,TBD-不确定,N-否,NA-不适用。
表2-2 需求说明书评测规范表
在需求说明书评测结束后,测试单位应将评测意见以专题报告的形式提交业主单位。
(2)概要设计说明书评测
①设计说明书的框架
软件设计规格说明的大纲如表2-3所示。软件设计的最终目标是要取得最佳方案。“最佳”指在所有候选方案中,满足节省开发费用,降低资源消耗,缩短开发时间的条件,选择能够赢得较高的生产率、较高的可靠性和可维护性的方案。在整个设计过程中,各个时期的设计结果需要经过一系列设计质量的评测,以便及时发现和解决在软件设计中出现的问题,防止把问题遗留到开发的后期,造成后患。
表2-3 软件设计规格说明大纲
②概要设计说明书评测的内容
a.可追溯性:即分析该软件的系统结构、子系统结构,确认该软件设计是否覆盖了所有已确定的软件需求,软件每一成份是否可追溯到某一项需求。
b.接口:即分析软件各部分之间的联系,确认该软件的内部接口与外部接口是否已经明确定义。模块是否满足高内聚和低耦合的要求。模块作用范围是否在其控制范围之内。
c.风险:即确认该软件设计在现有技术条件下和预算范围内是否能按时实现。
d.实用性:即确认该软件设计对于需求的解决方案是否实用。
e.技术清晰度:即确认该软件设计是否以一种易于翻译成代码的形式表达。
f.可维护性:从软件维护的角度出发,确认该软件设计是否考虑了方便未来的维护。
g.质量:即确认该软件设计是否表现出良好的质量特征。
h.各种选择方案:看是否考虑过其他方案,比较各种选择方案的标准是什么。
i.限制:评估对该软件的限制是否现实,是否与需求一致。
j.其他具体问题:对于文档、可测试性、设计过程等进行评估。
注意:软件系统的一些外部特性的设计,例如软件的功能、一部分性能以及用户的使用特性等,在软件需求分析阶段就已开始。
③衡量设计的技术标准
为评测设计是否达到目标,必须建立衡量设计的技术标准。如下:
a.设计出来的结构应是分层结构,从而建立软件成分之间的控制。
b.设计应当模块化,从逻辑上将软件划分为完成特定功能或子功能的构件。
c.设计应当既包含数据抽象,也包含过程抽象。
d.设计应当建立具有独立功能特征的模块。
e.设计应当建立能够降低模块与外部环境之间复杂连接的接口。
f.设计应能根据软件需求分析获取的信息,建立可驱动、可重复的方法。
④概要设计说明书评测规范
概要设计说明书评测规范如表2-4所示。填表说明:Y-是,TBD-不确定,N-否,NA-不适用。
表2-4 概要设计说明书评测规范
(3)详细设计说明书评测
详细设计说明书评测规范如表2-5所示。填表说明:Y-是,TBD-不确定,N-否,NA-不适用。
表2-5 详细设计说明书评测规范
(4)软件编码规范评测
程序良好的风格表现在以下四个方面:
①源程序文档化
a.符号名的命名
符号名即标识符,包括模块名、变量名、常量名、标号名、子程序名、数据区名以及缓冲区名等。这些名字应能反映其所代表的实际东西,应有一定实际意义。名字不是越长越好,应当选择精炼的、意义明确的名字。必要时可使用缩写名字,但要注意缩写规则要一致,并且要给每个名字加注释。同时,在一个程序中,一个变量只应用于一种用途。
b.程序的注释
注释是程序员日后与程序读者之间通信的重要手段。注释不是可有可无的。正规的程序文本中,注释行的数量占到整个源程序的1/3~1/2,甚至更多。注释有如下类型:
第一,序言性注释
通常置于每个程序模块的开头部分,应给出程序的整体说明,对于理解程序本身具有引导作用。有些软件开发部门对序言性注释做了明确而严格的规定,要求程序编制者逐项列出:
i.有关项目:包括程序标题;有关本模块功能和目的的说明;主要算法;
ii.接口说明:包括调用形式,参数描述,子程序清单;
iii.有关数据描述:包括重要的变量及其用途,约束或限制条件,以及其他有关信息;
iv.模块位置:在哪一个源文件中,或隶属于哪一个软件包;
v.开发简历:模块设计者,复审者,复审日期,修改日期及有关说明等。
第二,功能性注释
嵌在源程序体中,用以描述其后的语句或程序段是在做什么工作,或是执行下面的语句的功能。不需解释下面怎么做。
要点:描述一段程序,而不是每个语句;用缩进和空行,使程序与注释容易区别;注释要正确。
c.标准的书写格式
视觉组织用空格、空行和移行来实现。恰当地利用空格,可突出运算的优先性,减少编码的错误;自然的程序段之间可用空行隔开;移行也叫做向右缩格,指程序中的各行不必都在左端对齐,都从第一格起排列,这样做使程序完全分不清层次关系。对于选择语句和循环语句,把其中的程序段语句向右作阶梯式移行,使程序的逻辑结构更加清晰。
②数据说明
a.数据说明的次序应当规范化
数据说明次序规范化,使数据属性容易查找,有利于测试,排错和维护。原则上,数据说明的次序与语法无关,次序任意。出于阅读、理解和维护的需要,最好使其规范化,固定说明的先后次序。
b.说明语句中变量安排有序化
当多个变量名在一个说明语句中说明时,应当对这些变量按字母的顺序排列。带标号的全程数据也应当按字母的顺序排列。
c.使用注释说明复杂数据结构
若设计一复杂的数据结构,应当使用注释来说明在程序实现时该数据结构的固有特点。
③语句结构
语句构造力求简单、直接,不能为了片面追求效率而使语句复杂化。例如:
a.在一行内只写一条语句;
b.程序编写首先应当考虑清晰性;
c.程序要能直截了当地说明程序员的用意;
d.除非对效率有特殊的要求,程序编写要做到清晰第一,效率第二,不要为了追求效率而丧失了清晰性;
e.首先要保证程序正确,然后才要求提高速度,反过来说,在使程序高速运行时,首先要保证它是正确的;
f.避免使用临时变量而使可读性下降;
g.对编译程序做简单的优化;
h.尽可能使用库函数;
i.避免不必要的转移;
j.尽量采用基本的控制结构来编写程序;
k.避免采用过于复杂的条件测试;
l.尽量减少使用“否定”条件的条件语句;
m.尽可能用通俗易懂的伪代码来描述程序的流程,然后再翻译成必须使用的语言,数据结构要有利于程序的简化;
n.程序要模块化,使模块功能尽可能单一化,模块间的耦合能够清晰可见;
o.利用信息隐蔽,确保每一个模块的独立性;
p.从数据出发去构造程序;
q.不要修补不好的程序,要重新编写。
④输入和输出
a.要求
第一,输入和输出信息是与用户的使用直接相关的;
第二,输入和输出的方式和格式应当尽可能方便用户的使用;
第三,输入/输出风格还受到许多其他因素的影响。
b.设计和程序编写时应遵循的原则
第一,对所有的输入数据都要进行检验,识别错误的输入,以保证每个数据的有效性。
第二,检查输入项的各种重要组合的合理性,必要时报告输入状态信息。
第三,使输入的步骤和操作尽可能简单,并保持简单的输入格式。
第四,输入数据时,应允许使用自由格式输入。
第五,应允许缺省值。
第六,输入一批数据时,最好使用输入结束标志,而不要由用户指定输入数据数目。
第七,在交互式输入时,要在屏幕上使用提示符,明确提示交互输入的请求,指明可使用选择项的种类和取值范围。同时,在数据输入的过程中和输入结束时,也要在屏幕上给出状态信息。
第八,当程序设计语言对输入/输出格式有严格要求时,应保持输入格式与输入语句要求的一致性。
第九,给所有的输出加注解,并设计输出报表格式。
4.开发阶段
(1)单元测试(模块测试)
①简介
单元测试是针对软件设计的最小单位——程序模块,进行正确性检验的测试工作。其目的在于发现各模块内部可能存在的各种差错。单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。
②单元测试的内容
在进行单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的I/O条件和模块的逻辑结构,主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能鉴别和响应。故需对所有的局部的和全局的数据结构、外部接口和程序代码的关键部分,都要进行桌面检查和严格的代码审查。
在单元测试中进行的测试工作如图2-9所示,需要在以下五个方面对所测模块进行检查:
图2-9 单元测试的工作
a.模块接口测试
第一,在单元测试开始,应对所测模块的数据流进行测试。对模块接口可能需要如下的测试项目:调用所测模块时的输入参数与模块的形式参数在个数、属性、顺序上是否匹配;所测模块调用子模块时,其输入给子模块的参数与子模块中的形式参数在个数、属性、顺序上是否匹配;是否修改了只作输入用的形式参数;输出给标准函数的参数在个数、属性、顺序上是否正确;全局变量的定义在各模块中是否一致;限制是否通过形式参数来传送。
第二,当模块通过外部设备进行输入/输出操作时,必须附加如下的测试项目:文件属性是否正确;0PEN语句与CLOSE语句是否正确;规定的I/O格式说明与I/O语句是否匹配;缓冲区容量与记录长度是否匹配;在进行读写操作之前是否打开了文件;在结束文件处理时是否关闭了文件;正文书写/输入错误,以及I/O错误是否已检查并做了处理。
b.局部数据结构测试
模块的局部数据结构是最常见的错误来源,应设计测试用例以检查以下各种错误:
第一,不正确或不一致的数据类型说明;
第二,使用尚未赋值或尚未初始化的变量;
第三,错误的初始值或错误的缺省值;
第四,变量名拼写错或书写错;
第五,不一致的数据类型。
除局部数据之外的全局数据对模块的影响也需要查清。
c.路径测试
由于通常不可能做到穷举测试,所以在单元测试期间要选择适当的测试用例,对模块中重要的执行路径进行测试。应当设计测试用例查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误。对基本执行路径和循环进行测试,可以发现大量的路径错误。
第一,常见的不正确计算
运算的优先次序不正确或误解了运算的优先次序;运算的方式错,即运算的对象彼此在类型上不相容;算法错;初始化不正确;运算精度不够;表达式的符号表示不正确。
第二,常见的比较和控制流错误
不同数据类型的相互比较;不正确的逻辑运算符或优先次序;因浮点数运算精度问题而造成的两值比较不等;关系表达式中不正确的变量和比较符;“差1”错,即不正确地多循环了一次或少循环了一次;错误的或不可能的循环中止条件;当遇到发散的迭代时不能中止的循环;不适当地修改了循环变量等。
d.错误处理测试
比较完善的模块设计要求能预见出错的条件,并设置适当的出错处理,以便一旦程序出错,能对出错程序重做安排,保证其逻辑上的正确性。若出现下列情况之一,则表明模块的错误处理功能包含有错误或缺陷:
第一,出错的描述难以理解;
第二,出错的描述不足以对错误定位,不足以确定出错的原因;
第三,显示的错误与实际的错误不符;
第四,对错误条件的处理不正确;
第五,在对错误进行处理之前,错误条件已经引起系统的干预等。
e.边界测试
第一,在边界上出现错误是常见的。另外,在取最大值或最小值时也容易出错。因此,要特别注意数据流、控制流中刚好等于、大于或小于确定的比较值时出错的可能性。对这些地方要仔细地选择测试用例,认真加以测试。
第二,如果对模块运行时间有要求的话,要专门进行关键路径测试,以确定最坏情况下和平均意义下影响模块运行时间的因素。该类信息对进行性能评价十分有用。项目负责人应当关心测试的结果。所有测试用例和测试结果都是模块开发的重要资料,必须妥善保存。
第三,模块测试针对的程序规模较小,易于查错;发现错误后容易确定错误的位置,易于排错,同时多个模块可以并行测试。做好模块测试可为后续的测试打下良好的基础。
③单元测试的步骤
通常单元测试在编码阶段进行。在源程序代码编制完成,经过评审和验证,确认没有语法错误之后,开始进行单元测试的测试用例设计。利用设计文档,设计可以验证程序功能、找出程序错误的多个测试用例。对于每一组输入,应有预期的正确结果。模块不是一个独立的程序,在考虑测试模块时,同时要考虑其和外界的联系,用一些辅助模块去模拟与所测模块相联系的其他模块。
a.辅助模块的分类
第一,驱动模块(driver)
驱动模块相当于所测模块的主程序。接收测试数据,将这些数据传送给所测模块,最后再输出实测结果。
第二,桩模块(stub)(存根模块)
该模块用以代替所测模块调用的子模块。桩模块可以做少量的数据操作,不需要把子模块所有功能都带进来,但不允许什么事情也不做。
b.测试环境
所测模块、与其相关的驱动模块及桩模块共同构成了一个“测试环境”,如图2-10所示。驱动模块和桩模块的编写会给测试带来额外的开销。因为二者在软件交付时不作为产品的一部分一同交付,而且二者的编写需要一定的工作量。特别是桩模块,不能只简单地给出“曾经进入”的信息,为了能够正确地测试软件,桩模块可能需要模拟实际子模块的功能。
图2-10 单元测试的测试环境
c.注意事项
模块的内聚程度高,可以简化单元测试过程。
第一,如果各模块只完成一种功能,则需要的测试用例数目将明显减少,模块中的错误也容易被预测和发现。
第二,如果模块要完成多种功能,且以程序包(package)的形式出现的,此时可将该模块看成由几个小程序组成。必须对其中的每个小程序先进行单元测试,对关键模块还要做性能测试。对支持某些标准规程的程序,更要着手进行互联测试。有人把此种情况特别称为模块测试,以区别单元测试。
(2)集成测试(组装测试或联合测试)
通常,在单元测试的基础上,需要将所有模块按照概要设计说明书和详细设计说明书的要求进行组装。
①组装时需要考虑的问题
a.在把各个模块连接起来的时候,穿越模块接口的数据是否会丢失;
b.一个模块的功能是否会对另一个模块的功能产生不利的影响;
c.各个子功能组合起来,能否达到预期要求的父功能;
d.全局数据结构是否有问题;
e.单个模块的误差累积起来,是否会放大,以至达到不能接受的程度。
注意:子系统的集成测试称为部件测试,其所做的工作是要找出组装后的子系统与系统需求规格说明之间的不一致。选择何种方式把模块组装起来形成可运行的系统,直接影响模块测试用例的形式、所用测试工具的类型、模块编号的次序和测试的次序以及生成测试用例的费用和调试的费用。
②模块组装成为系统的方式
a.一次性组装方式(整体拼装)
第一,概述
一次性组装方式是一种非增殖式组装方式。使用该方式,首先对每个模块分别进行模块测试,再把所有模块组装在一起进行测试,最终得到要求的软件系统。
第二,示例说明
如:有一模块系统结构,如图2-11(a)所示。其单元测试和组装顺序如图2-11(b)所示。
(a)
(b)
图2-11 一次性组装方式
如图2-11(b)所示,模块dl,d2,d3,d4,d5是对各个模块做单元测试时建立的驱动模块,sl,s2,s3,s4,s5是为单元测试而建立的桩模块。该一次性组装方式试图在辅助模块的协助下,在分别完成模块单元测试的基础上,将所测模块连接起来进行测试。但是由于程序中不可避免地存在涉及模块间接口、全局数据结构等方面的问题,所以一次试运行成功的可能性并不是很大。导致发现有错误,却找不到原因,查错和改错都会遇到困难。
b.增殖式组装方式(渐增式组装)
首先对一个个模块进行模块测试,然后将这些模块逐步组装成较大的系统,在组装的过程中边连接边测试,以发现连接过程中产生的问题。最后通过增殖逐步组装成为要求的软件系统。
第一,自顶向下的增殖方式
该组装方式是将模块按系统程序结构,沿控制层次自顶向下进行组装。具体步骤为:
i.首先以主模块作为所测模块兼驱动模块,所有直属于主模块的下属模块全部用桩模块代替,对主模块进行测试。
ii.再采用深度优先(自顶向下的增殖方式,如图2-12所示)或广度优先的策略,用实际模块替换相应的桩模块,再用桩模块代替它们的直接下属模块,与已测试的模块或子系统组装成新的子系统。
图2-12 自顶向下的增殖方式
iii.然后,进行回归测试(即重新执行以前做过的全部测试或部分测试),排除组装过程中引入新的错误的可能。
iv.判断是否所有的模块都已组装到系统中。如果是,则结束测试;否则,转到B去执行。
总之,自顶向下的增殖方式在测试过程中较早地验证了主要的控制和判断点,能够增强开发者和用户成功的信心。在一个功能划分合理的程序模块结构中,判断常常出现在较高的层次里,如果选用按深度方向组装的方式,可以首先实现和验证一个完整的软件功能,可先对逻辑输入的分支进行组装和测试,检查和克服潜藏的错误和缺陷,验证其功能的正确性,为其后对主要加工分支的组装和测试提供了保证。此外,功能可行性较早地得到证实。
第二,自底向上的增殖方式
该组装方式是从程序模块结构的最底层模块开始组装和测试。因为模块是自底向上进行组装的,对于一给定层次的模块,其子模块(包括子模块的所有下属模块)已经组装并测试完成,所以不再需要桩模块。在模块的测试过程中需要从子模块得到的信息可以通过直接运行子模块得到。步骤为:
i.首先由驱动模块控制最底层模块的并行测试;也可把最底层模块组合成实现某一特定软件功能的簇,由驱动模块控制它进行测试。
ii.再用实际模块代替驱动模块,与其已测试的直属子模块组装成为子系统。
iii.然后,为子系统配备驱动模块,进行新的测试。
iv.最后判断是否已组装到达主模块。是,则结束测试;否则,执行B。
以如图2-11(a)所示的一次性组装方式系统结构为例,可以说明自底向上组装和测试的顺序,如图2-13所示。
图2-13 自底向上的增殖方式
第三,混合增殖式测试
i.自顶向下增殖方式的优缺点
缺点为:需要建立桩模块。要使桩模块能够模拟实际子模块的功能十分困难,因为,桩模块在接收了所测模块发送的信息后,需要按照它所代替的实际子模块功能返回应该回送的信息,这必将增加建立桩模块的复杂度,而且导致增加一些附加的测试。
由于涉及复杂算法和真正输入/输出的模块一般在底层,该模块最容易出问题,到组装和测试的后期才遇到这些模块,一旦发现问题,就会导致过多的回归测试。
优点为:能够较早地发现主要控制方面的问题。
ii.自底向上增殖方式的优缺点
缺点为:“程序一直未能作为一个实体存在,直到最后一个模块加上去后才形成一个实体”。即在自底向上组装和测试的过程中,对主要的控制直到最后才接触到。
优点为:不需要桩模块,而建立驱动模块一般比建立桩模块容易,同时由于涉及到复杂算法和真正输入/输出的模块最先得到组装和测试,可以把最容易出问题的部分在早期解决。此外自底向上增殖的方式可以实施多个模块的并行测试,提高测试效率。
通常是把以上两种方式结合起来进行组装和测试。
③关键模块的特征
在进行集成测试时,测试者应当确定关键模块,对这些关键模块及早进行测试。关键模块至少应具有以下几种特征之一:
a.满足某些软件需求;
b.在程序的模块结构中位于较高的层次(高层控制模块);
c.较复杂、较易发生错误;
d.有明确定义的性能要求。
在做回归测试时,也应该集中测试关键模块的功能。
④集成测试的组织和实施
在制定测试计划时,应考虑如下因素:
a.采用何种系统组装方法来进行集成测试;
b.集成测试过程中连接各个模块的顺序;
c.模块代码编制和测试进度是否与集成测试的顺序一致;
d.测试过程中是否需要专门的硬件设备。
解决了上述问题之后,就可以列出各个模块的编制、测试计划表,标明每个模块单元测试完成的日期、首次集成测试的日期、集成测试全部完成的日期、以及需要的测试用例和所期望的测试结果。在缺少软件测试所需要的硬件设备时,应检查该硬件的交付日期是否与集成测试计划一致。此外,在测试计划中需要考虑测试所需软件的准备情况。
⑤集成测试完成的标志
a.成功地执行了测试计划中规定的所有集成测试;
b.修正了所发现的错误;
c.测试结果通过了专门小组的评审。
⑥集成测试过程
a.集成测试应由专门的测试小组来进行,测试小组由有经验的系统设计人员和程序员组成。整个测试活动要在评审人员出席的情况下进行。
b.在完成预定的集成测试工作之后,测试小组应负责对测试结果进行整理、分析,形成测试报告。测试报告中要记录实际的测试结果、在测试中发现的问题、解决这些问题的方法以及解决之后再次测试的结果,此外还应提出目前不能解决,还需要管理人员和开发人员注意的一些问题,提供测试评审和最终决策,以提出处理意见。
c.集成测试需要提交的文档有集成测试计划、集成测试规格说明和集成测试分析报告。
(3)确认测试
①任务
验证软件的功能和性能及其他特性是否与用户的要求一致。对软件的功能和性能要求在软件需求规格说明中有明确规定。
②分类
确认测试一般由独立的第三方测试机构进行,其包括以下两类:
a.进行有效性测试
在模拟的环境下,运用黑盒测试的方法,验证所测软件是否满足需求规格说明书列出的需求。因此,需制定测试计划、测试步骤以及具体的测试用例。同时,对其他软件需求,例如可移植性、可靠性、易用性、兼容性、可维护性等,也要进行测试,确认是否满足。在全部软件测试的测试用例运行完后,所有的测试结果可以分为以下两类:
第一,测试结果与预期的结果相符
说明软件的这部分功能或性能特征与需求规格说明书相符合,从而接受这部分程序。
第二,测试结果与预期的结果不符
说明软件的这部分功能或性能特征与需求规格说明不一致,故要为其提交一份问题报告。
b.软件配置复查
第一,目的:保证软件配置的所有成分都齐全,各方面的质量都符合要求,具有维护阶段所必须的细节,且已经编排好分类的目录。
第二,注意:在确认测试的过程中,应当严格遵守用户手册和操作手册中规定的使用步骤,以便检查文档资料的完整性和正确性。
(4)系统测试
①简介
系统测试是将通过集成测试的软件,作为整个基于计算机系统的一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其他系统元素结合在一起,在实际或者模拟运行(使用)环境下,对计算机系统进行一系列测试。
②目的
通过与系统的需求定义作比较,发现软件与系统定义不符合或与之矛盾的地方。
(5)验收测试
①简介
以用户为主的测试。软件开发人员和质量保证人员应参加。由用户参加设计测试用例。使用用户界面输入测试数据,并分析测试的输出结果。一般使用生产中的实际数据进行测试。
②发展
a.目前在国内实际软件开发,特别是系统集成的过程中,验收测试往往在系统测试完成后,项目最终交付前进行
第一,验收测试的测试计划、测试方案与测试案例一般由开发方制定,由用户方与监理方联合进行评审。
第二,验收小组由开发方、用户方、监理方代表、主管单位领导及行业专家构成。
第三,验收测试往往不是对系统的全覆盖测试,而是针对用户的核心业务流程进行的测试;同时,测试的执行人员也不是开发方的测试组成员,而是由用户方的使用人员完成。
b.近年来,越来越多的开发方及用户方认识到对项目进行最终验收测试的重要意义,故由第三方完成的专业化全覆盖型技术测试得到了广泛应用
5.软件验证与确认(V&V)过程
软件验证与确认(V&V)过程是贯穿软件生命周期的重要的质量保证过程。
(1)V&V基本概念
①验证(Verification):通过检查和提供客观证据,证实是否以满足规定的需求。
②确认(Validation):通过检查和提供客观证据,证实预期用途的需求是否得到满足。
③独立验证和确认(IV&V Independent Verification and Validation):由在技术、管理和财务上与开发组织有规定程度独立性的组织执行的V&V过程。
V&V框架是由与软件开发过程同步的V&V过程、各阶段V&V活动和任务组成,如图2-14所示。
图2-14 V&V结构
对每个V&V活动都规定了它的输入、任务和输出,如图2-15所示。
图2-15 V&V活动过程
(2)软件V&V过程
软件的V&V过程是确定按照规定的软件过程开发的产品是否符合活动的要求,以及软件是否满足它的预期用途和用户需要。软件的V&V过程包括软件产品和过程的分析、评价、评审、审核、评估和测试。
①软件生存周期的V&V过程框架
整个软件生存周期的V&V过程框架结构描述了各阶段的V&V过程、活动和任务的层次关系,如图2-l6所示。
图2-16 V&V过程、活动和任务的层次关系
②软件开发过程的V&V概述
IEEE Std 1012-1998中开发过程的V&V,如图2-17所示。
图2-17 软件开发过程的V&V
(3)软件V&V过程中的测试
①测试过程
测试过程包括:测试计划过程、测试设计过程、测试执行过程和测试结束过程。如图2-18所示。
图2-18 软件测试过程
②需求V&V活动中的测试
需求V&V活动中有两项测试任务:系统V&V测试计划生成和验证、验收V&V测试计划生成和验证。两项V&V的任务、输入和输出如表2-6所示。
表2-6 需求V&V活动中的测试任务、输入和输出
③设计V&V活动中的测试
设计V&V活动中有三项测试任务:单元V&V测试计划生成和验证、集成V&V测试计划生成和验证与V&V测试计划生成和验证。三项V&V的任务、输入和输出如表2-7和表2-8所示。
表2-7 设计V&V活动中的测试任务、输入和输出
2-8 设计V&V活动中的测试任务、输入和输出(续)
④实现V&V活动中的测试
实现V&V活动中有三项测试任务:V&V测试用例生成和验证、V&V测试规程生成和验证以及部件V&V测试计划执行和验证。三项V&V的任务、输入和输出如表2-9所示。
表2-9 实现V&V活动中的测试任务、输入和输出
(4)软件测试V&V活动
①覆盖范围与目标
测试V&V活动覆盖了集成测试、系统测试和验收测试。V&V的目标是确保通过执行集成测试、系统测试和验收测试使软件需求和分配给软件的系统需求得到满足。测试V&V活动及其与软件生存期的关系如图2-19所示。
图2-19 V&V测试产品和测试执行任务的时段图
②工作要求
测试的V&V工作应生成自己的V&V测试件(包括计划、设计、用例和规程),执行并记录自己的测试,并对照软件需求验证测试计划、设计、用例、规程和结果;测试的V&V工作应验证测试活动和测试件(包括计划、设计、用例、规程和执行结果)。测试V&V活动的任务、输入与输出的关系如表2-10所示。
表2-10 测试V&V活动中的测试任务、输入和输出
2.8 软件失效分类与管理
一、软件失效的分类
1.软件测试使用的各术语
(1)软件错误(software error)
软件错误指在软件生存期内的不希望或不可接受的人为错误,其结果会导致软件缺陷的产生。软件错误是一种人为过程,相对于软件本身,是一种外部行为。
(2)软件缺陷(software defect)
①简介
软件缺陷存在于软件(文档、数据、程序)之中的那些不希望或不可接受的偏差,如少一逗点等。其结果是软件运行于某一特定条件时出现软件故障,此时称软件缺陷被激活。
②《软件测试》对软件缺陷的定义
按照一般定义,只要软件出现的问题符合下列5种情况的任何一种,就称为软件缺陷:
a.软件未达到产品说明书中标明的功能。
b.软件出现了产品说明书中指明的不会出现的错误。
c.软件功能超出了产品说明书指明的范围。
d.软件未达到产品说明书虽未指出但应达到的目标。
e.软件测试人员认为软件难以理解、不易使用、运行速度慢,或最终用户认为不好使用。
③产生的原因
a.主要来自于产品说明书的编写和产品方案设计
由于产品说明书编写得不全面、不完整和不准确,而且经常更改,或者整个开发组没有很好地沟通和理解。即出自于软件需求说明书的问题,或开发人员对需求说明书的理解与沟通不足。
b.设计方案即软件设计说明书
此为程序员开展软件计划和构架的地方。此处产生软件缺陷的原因与产品说明书或需求说明书是一样的,片面、多变、理解与沟通不足。
总之,软件缺陷是开发的软件与软件需求说明书、设计说明书的不一致;软件的实现未满足目标用户的潜在需求。
(3)软件故障(software fault)
软件故障指软件运行过程中出现的一种不希望或不可接受的内部状态。此时若无适当措施(容错)加以及时处理,便产生软件失效。显然,软件故障是一种动态行为。当软件出现故障,即系统不能同软件设计和用户要求那样运行而导致失效时,就需要有故障恢复措施,以保证故障恢复后的继续执行。
(4)软件失效(software failure)
①概述
软件失效指软件运行时产生的一种不希望或不可接受的外部行为结果。软件失效机理可描述为:软件错误→软件缺陷→软件故障→软件失效,是系统行为对用户要求的偏离,是一种面向用户的概念。失效意味着系统的运行。
②发现
只有在执行程序过程中才会发现软件失效,发现的潜在失效可以是设计审查、代码阅读和其他方法产生的结果。不能把文档错误计算在软件错误之内,因为文档并不直接影响程序的执行。虽然用户接受的是程序使用的错误信息,文档错误可能会导致用户的失效。但是,用户并不是软件成分,不能把用户看成是与失效和可靠性有关的单独的系统成分。
③分类
对失效严重程度进行分类,主要是为了结合失效频率来确定失效的优先级。常见的分类标准包括对人员生命、成本和系统能力的影响。
④失效强度
失效强度常常应用于软件可靠性工程中,最初是指单位时间内的失效次数;基于软件大量的使用经验,失效强度用每个自然单元出现的失效数目来表示更加方便。失效强度是表示可靠性的另一种形式。
2.总结
软件错误是一种人为错误。一个软件错误必定产生一个或多个软件缺陷。当一个软件缺陷被激活时,便产生一个软件故障;同一个软件缺陷在不同条件下被激活,可能产生不同的软件故障。软件故障如果未及时地采取容错措施加以处理,便不可避免地导致软件失效;同一个软件故障在不同条件下可能产生不同的软件失效。
二、缺陷与错误分布
通过对错误分布情况的仔细分析,可以帮助我们将测试的主要精力更好地集中到最有价值的地方,如图2-20显示了缺陷与错误的分布情况。
图2-20 缺陷与错误的分布情况
开发早期的错误通常很多,且这些错误会转移到后期。即错误不是自封闭,当转移到后面的组件中,往往会以新的形式出现。所有的错误都要付出代价,故测试贯穿开发的全过程。在使用测试资源方面任何有意义的改进都能极大地降低开发成本。
三、缺陷与错误严重性和优先级
1.划分的通用原则
给软件缺陷与错误划分严重性和优先级的通用原则如下:
(1)表示软件缺陷所造成的危害的恶劣程度;
(2)优先级表示修复缺陷的重要程度与次序。
2.严重级
(1)严重:系统崩溃、数据丢失、数据毁坏。
(2)较严重:操作性错误、错误结果、遗漏功能。
(3)一般:小问题、错别字、UI布局、罕见故障。
(4)建议:不影响使用的瑕疵或更好的实现。
3.优先级
(1)最高优先级:立即修复,停止进一步测试。
(2)次高优先级:在产品发布之前必须修复。
(3)中等优先级:如果时间允许应该修复。
(4)最低等优先级:可能会修复,但也能发布。
4.说明
一般的严重性和优先级的划分用数字l~4表示,有的用小数字表示的级别最高,而有的用大数字表示级别高。同样的错误和缺陷,在不同的开发过程或软件的不同部分,严重性和优先级将有所变化,要具体情况具体分析。
四、软件错误跟踪管理
1.错误跟踪管理
为了正确地跟踪每个软件错误的处理过程,通常将软件测试发现的每个错误作为一条记录输入指定的错误跟踪管理系统。作为一个错误跟踪管理系统,需要正确记录错误信息和错误处理信息的全部内容。
(1)Bug记录信息
①测试软件名称;
②测试版本号;
③测试人名称;
④测试事件;
⑤测试软件和硬件配置环境;
⑥发现软件错误的类型;
⑦错误的严重等级;
⑧详细步骤;
⑨必要的附图;
⑩测试注释。
(2)Bug处理信息
①处理者姓名;
②处理时间;
③处理步骤;
④错误记录的当前状态。
正确的错误数据库权限管理是错误跟踪管理系统的重要考虑要素,一般要保证对于添加的错误不能从数据库中删除。
2.软件错误的状态
(1)新信息(New):测试中新报告的软件Bug;
(2)打开(Open):被确认并分配给相关开发人员处理;
(3)修正(Fixed):开发人员已完成修正,等待测试人员验证;
(4)拒绝(Declined):拒绝修改Bug;
(5)延期(Deferred):不在当前版本修复的错误,下一版修复;
(6)关闭(Closed):Bug已被修复。
3.错误管理流程
错误管理的流程可以概括为以下内容:
(1)测试人员提交新的错误入库,错误状态为“New”
(2)高级测试人员验证错误
①如果确认是错误,分配给相应的开发人员,设置状态为“Open”;
②如果不是错误,则拒绝,设置为“Declined”状态。
(3)开发人员查询状态为“Open”的错误,作如下处理:
①如果不是错误,则置状态为“Declined”;
②如果是错误,则修复并置状态为“Fixed”;
③如果不能解决的错误,要留下文字说明并保持错误为“Open”状态;
④对于不能解决和延期解决的错误,不能由开发人员自己决定,一般要通过某种会议(评审会)通过才能认可。
(4)测试人员查询状态为“Fixed”的错误,验证错误是否己解决
①如问题解决,置错误的状态为“Closed”;
②如问题没有解决,则置状态为“Reopen”。
4.错误流程管理原则
(1)为了保证错误处理的正确性,需要有丰富测试经验的测试人员验证发现的错误是否是真正的错误,书写的测试步骤是否准确,可以重复;
(2)每次对错误的处理都要保留处理信息,包括处理姓名、时间、处理方法、处理意见、Bug状态;
(3)拒绝或延期处理错误不能由程序员单方面决定,应该由项目经理、测试经理和设计经理共同决定;
(4)错误修复后必须由报告错误的测试人员验证,确认已经修复后,才能关闭错误;
(5)加强测试人员与程序员之间的交流,对于某些不能重复的错误,可以请测试人员补充详细的测试步骤和方法,以及必要的测试用例。
2.9 白盒测试
一、概述
白盒测试又称结构测试或逻辑驱动测试,是按照程序内部的结构测试程序,通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进行,检验程序中的每条通路是否都能按预定要求正确工作。测试人员依据程序内部逻辑结构相关信息,设计或选择测试用例,对程序所有逻辑路径进行测试,通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致。
二、软件测试方法
1.静态测试方法
不要求在计算机上实际执行所测程序,主要使用人工的模拟技术对软件进行分析和测试。
2.动态测试方法
通过输入一组预先按照一定的测试准则构造的实例数据来动态运行程序,而达到发现程序错误的过程。
2.10 黑盒测试
一、概述
黑盒测试又称功能测试,通过测试来检测各功能是否都能正常使用。在测试时,把程序看作不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试,只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息。
黑盒测试是以用户的角度,从输入数据与输出数据的对应关系出发进行测试的,它着眼于程序外部结构,主要针对软件界面和软件功能进行测试,但是黑盒测试无法发现外部特性本身或规格说明的规定存在的问题。很明显,如果外部特性本身有问题或规格说明的规定有误,用黑盒测试方法是发现不了的。
二、试图发现的错误
黑盒测试法注重于测试软件的功能需求,主要试图发现下列几类错误:
(1)功能不正确或遗漏;
(2)界面错误;
(3)数据库访问错误;
(4)性能错误;
(5)初始化和终止错误等。
三、用例设计方法
1.等价类划分
把程序的输入域划分成若干部分,然后从每个部分中选取少数代表性数据作为测试用例。每类的代表性数据在测试中的作用等价于这类中的其他值。
2.边界值分析
通过选择等价类边界的测试用例。边界值分析法不仅重视输入的条件边界,且必须考虑输出域边界。
3.错误推测设计方法
基于经验和直觉推测程序中所有可能存在的各种错误,从而有针对性地设计测试用例的方法。
4.因果图方法
从用自然语言书写的程序规格说明的描述中找出因(输入条件)和果(输出或程序状态的改变),可通过因果图转换为判定表。
5.正交试验设计法
使用已经造好的正交表格来安排试验并进行数据分析的一种方法,目的是用最少的测试用例达到最高的测试覆盖率。
2.11 自动化测试
一、概述
1.引入自动化测试的原因
(1)人工测试的工作量太大,同时还需要额外的时间来培养测试人员等。为了确保复杂的企业级应用在不同环境下都能可靠地运行,需能简单操作的测试工具来自动完成应用程序的功能性测试。
(2)为了在终端用户正式使用前,对应用系统各个环节的质量、可靠性和可扩展性进行测试和评价,需要利用适用于不同体系架构的自动负载压力的测试工具,来预测系统行为,并为系统优化提供依据。
(3)为了更加快速、有效地对软件进行测试,提高软件产品的质量,必然会利用测试工具,也必然会引入自动化测试。
2.自动化测试的简介
(1)定义
自动化测试是指通过测试工具或其他手段,按照测试工程师的预定计划对软件产品进行自动的测试,是软件测试的一个重要的组成部分,能够完成许多手工无法完成或者难以实现的一些测试工作。正确、合理地实施自动化测试,能够快速、全面地对软件进行测试,从而提高软件质量,节省经费,缩短产品发布周期。
(2)内容
自动化测试涉及到测试流程、测试体系、自动化编译以及自动化测试等方面的整合。要让测试能够自动化,不仅是技术、工具的问题,更是一个公司和组织的文化问题。首先公司要从资金、管理上给予支持;其次要有专门的测试团队去建立适合自动化测试的测试流程和测试体系;最后把源代码从受控库中取出、编译、集成、发布并进行自动化的功能和性能等方面的测试。
二、自动化测试的优势与局限
1.自动化测试的优势
(1)表现
自动化测试能够替代大量手工测试工作,避免重复测试,同时,能够完成大量手工无法完成的测试工作,具有以下优点:
①提高测试质量
当软件产品的部分或全部,或者应用环境被修改时都需要对软件产品重新进行测试,其目的是验证修改后的系统或者产品的质量是否还符合规格说明。由于自动化测试工具提供了简便的回归测试,能以便利的方式验证软件产品中是否有新的错误进入,既减少了重复手工输入的工作量,保证了测试案例的一致性,避免了人为因素,也可以使测试达到测试每个质量特性的目的,从而提高软件测试的质量。
②提高测试效率,缩短测试工作时间
自动化测试工具可以较好地执行这些频繁的测试任务。充分合理地使用了测试工具,可以减轻测试工程师的手工测试工作,并且测试工具还可以把控制和管理引入整个测试过程,能够保证测试的进度。
③提高测试覆盖率
a.通过自动化测试工具的录制回放及数据驱动来测试功能,可以提高测试覆盖率;
b.通过测试工具的辅助分析功能,可以提高测试的深度。
④执行手工测试不能完成的测试任务
有些非功能性方面的测试,例如,压力测试、负载测试、大数据量测试、崩溃性测试等,依靠人工是不可能实现的。
⑤更好地重现软件缺陷的能力
自动化测试具有更好的一致性和可重复性,由于每次自动化测试运行的脚本是相同的,所以每次执行的测试具有一致性。因此,很容易发现被测软件的任何改变。
⑥更好地利用资源
理想的自动化测试能够按计划完全自动地运行,在开发人员和测试人员不可能实行三班倒的情况下,自动化测试可以胜任这个任务,例如,完全可以在周末或者晚上执行测试。这样充分地利用资源,避免了开发和测试之间的冲突。
⑦增进测试人员与开发人员之间的合作伙伴关系
测试工程师为了更好地使用自动化测试工具,需要对开发技术有深入的理解和实践,因此测试工程师也有比开发工程师更多、更平等地交流的机会,自动化测试为测试工程师与程序开发人员协同工作提供了一种便利的手段,双方将有更多的合作机会与获得互相的尊重。
(2)由于自身优势而适用的范围
测试工具能够提高软件质量,改进测试过程,因此在许多公司中得到了广泛应用,由于自动化测试工具自身的特点,为达到较高的投资回报率,在以下项目和环境中更适合使用自动化测试工具:
①需要反复进行的工作
在持续修改软件功能的项目中,对功能的测试需要反复进行,人工测试工作量极大。功能性测试工具能够自动进行重复性的工作,验证软件的修改是否引入了新的缺陷,旧的缺陷是否已经修改。从而减少人工测试的工作量。
②负载压力测试
需要模拟大量并发用户和大数据量,这样的测试用手工不能或不能很好地完成,而自动化测试工具则可以很好地解决该问题,在测试脚本运行过程中不需要人工干预,并且能够充分利用非工作时间。
③公司有大量的测试人员和开发人员,其合作完成一个产品,借助于自动化的测试管理工具,使得在产品的生命周期中进行有效管理和合作,会取得事半功倍的效果。
④如果需要对测试系统后台或者内部的性能特性,进行故障定位和性能调优,可选择自动化测试工具。
2.自动化测试的局限性
(1)自动化测试的局限性表现的领域
①定制型项目
为客户定制的项目,甚至采用的开发语言、运行环境也是客户特别要求的,开发公司在这方面的测试积累少,这样的项目不适合作自动化功能测试。
②周期很短的项目
项目周期很短,相应的测试周期也很短,因此花大量精力准备的测试脚本,不能得到重复地利用。但是为了某种特定的测试目的专门执行的测试任务除外。
③业务规则复杂的对象
业务规则复杂的对象有复杂的逻辑关系和运算关系,工具很难实现,或者要实现这些测试过程,需要投入的测试准备时间比直接进行手工测试所需的时间更长。
④人体感观与易用性测试
界面的美观、声音的体验、易用性的测试,无法用测试工具来实现。
⑤不稳定的软件
如果软件不稳定,则会由于这些不稳定因素导致自动化测试失败,或者致使测试结果本身就无效。
⑥涉及物理交互
自动化测试工具不能很好地完成与物理设备的交互,比如刷卡器的测试等。
(2)误区
鉴于自动化测试工具的局限性,测试工程师,在考虑选用自动化测试的过程中,还需了解公司领导、项目负责人等对于自动化测试的期望并消除他们一些不正确的期望,如下:
①自动化测试可以完成一切测试工作
很多人认为自动化测试工具可以完成一切测试工作,从测试计划到测试执行,再到测试结果分析,不需要任何人工干预等,然而现实中还没有也不会有该种自动化测试工具。在现实中有关的测试设计、测试案例以及一些关键的测试任务需要人工参与,即自动化测试是对手工测试的辅助和补充,永远不可能取代手工测试。
②测试工具可适于所有的测试
每种自动化测试工具都有它的应用范围和可用对象,一种自动化测试工具不能满足所有的测试需求。针对不同的测试目的和测试对象,应该选择合适的测试工具进行测试,在很多情况下,需要利用多种测试工具才能完成测试工作。
③测试工具能使工作量大幅度降低
事实上,引入自动化测试工具不会马上减轻测试工作。只有在正确合理地使用测试工具的情况下,并有一定的技术积累后,测试工作量才能逐渐减轻。
④测试工具能实现百分之百的测试覆盖率
由于自动化测试可以增加测试覆盖的深度和广度,但因为穷举测试必须用所有可能的数据,包括有效的和无效的测试数据,所以在有限的资源下不可能进行百分之百的彻底测试。
⑤自动化测试工具容易使用
自动化测试并不简单,捕获的操作是否正确以及脚本编辑是否合理都会影响测试结果,因此,自动化测试需要更多的技能,也需要更多的培训。
⑥自动化测试能发现大量的新缺陷
发现更多的新缺陷是手工测试的主要目的,不能期望自动化测试去发现更多新缺陷,事实上自动化测试主要用于发现老缺陷。
三、选择合适的自动化测试工具
1.自动化测试工具分类
按照测试工具的主要用途和应用领域,可分为以下几类:
(1)负载压力测试工具
①概述
负载压力测试工具的主要目的是度量应用系统的可扩展性和性能,是一种预测系统行为和性能的自动化测试工具。通过模拟成百上千直至上万用户并发执行关键业务,而完成对应用程序的测试,在实施并发负载过程中通过实时性能监测来确认和查找问题,并针对所发现问题对系统性能进行优化,确保应用的成功部署。
②特点
能够对整个企业架构进行测试,通过这些测试,企业能最大限度地缩短测试时间,优化性能和加速应用系统的发布周期。
③代表
LoadRunner、QALoad、SILKPERFORMA V和E-Test Suite等。
(2)功能测试工具
①简介
通过自动录制、检测和回放用户的应用操作,将被测系统的输出记录同预先给定的标准结果进行比较。
②特点
能够有效地帮助测试人员对复杂的企业级应用的不同发布版本的功能进行测试,提高测试人员的工作效率和质量。其主要目的是用于检测应用程序是否能够达到预期的功能并正常运行。可以大大减轻黑盒测试的工作量,在迭代开发的过程中,能够很好地进行回归测试。
③代表
WinRunner、QARun等。
(3)白盒测试工具
①静态测试工具
a.简介
直接对代码进行分析,不需要运行代码,也不需要对代码编译链接和生成可执行文件。
b.特点
一般是对代码进行语法扫描,找出不符合编码规范的地方,根据某种质量模型评价代码的质量,生成系统的调用关系图等。
c.代表
Logiscope软件和PRQA软件。
②动态测试工具
a.简介
一般采用“插桩”的方式,向代码生成的可执行文件中插入一些监测代码,用来统计程序运行时的数据。其与静态测试工具最大的不同就是动态测试工具要求被测系统实际运行。
b.代表
动态测试工具的代表有DevPartner、Rational Purify系列等。
(4)网络测试工具
①简介
网络测试工具主要包括网络故障定位工具、网络性能监测工具、网络仿真模拟工具等。
②特点
网络测试工具分析分布式应用性能,关注应用、网络和其他元素(如服务器)内部的交互式活动,以便使网络管理员能够了解网络不同位置和不同活动之间应用的行为。
③应用
a.用在交易执行过程中、Web查找和检索中或在日常数据库上载/下载中跟踪应用行为。
b.在会话级、代码级,甚至在帧级和包级观察应用的行为过程,并深入代码内部的结构,解析有问题的会话。
(5)测试管理工具
①简介
用于对测试进行管理。通常,测试管理工具对测试需求、测试计划、测试用例、测试实施进行管理,并且测试管理工具还包括对缺陷踪管理。
②特点
a.测试管理工具能让测试人员、开发人员或其他的IT人员通过一个中央数据仓库,在不同的地方就能交互信息。
b.测试管理工具将测试过程流水化,从测试需求管理到测试计划、测试日程安排、测试执行到出错后的错误跟踪,实现全过程的自动化管理。
③代表
TestDirector、TestManger、TrackRecord等。
(6)测试辅助工具
本身并不执行测试,例如可以生成测试数据,为测试提供数据准备等。
2.自动化测试应用策略
(1)测试过程中应用测试工具的目的
①提高测试质量;
②减少测试过程中的重复劳动;
③实现测试自动化,解决手工测试不能解决的问题。
(2)应用自动化测试时需考虑的问题
①选择合适的自动化测试工具
面对众多不同用途的测试工具,如何正确地选择合适的测试工具,是能否正常实施自动化测试的前提,选用工具时,可从以下几个方面来权衡:
a.功能
功能为最关注的内容。选择适用的测试工具。除了侧重基本的功能,以下的功能需求也可作为选择测试工具的参考:
第一,报表功能
测试工具生成的结果最终要由测试人员进行解释,且查看最终报告的人员不一定对测试很熟悉,因此,测试工具能否生成结果报表,能够以什么形式提供报表是需要考虑的因素。
第二,测试工具的集成能力
测试工具的集成能力为必须考虑的因素,集成包括两个方面的意思:测试工具能否和开发工具进行良好的集成以及测试工具能够和其他测试工具进行良好的集成。
第三,操作系统和开发工具的兼容性
测试工具可否跨平台,是否适用于公司目前使用的开发工具。
b.价格
除功能外,价格是最重要的因素。作为一个测试工程师,在选择购买测试工具时,应该具有成本意识,必须利用有限的资金满足企业对测试工具的大部分需求。
c.测试工具的长期投资考虑
测试工具引入的目的是测试自动化,引入工具需要考虑工具的连续性和一致性,即对测试工具的选择必须有一个全盘的考虑,分阶段、逐步的引入测试工具。
②确定测试工具的应用时机
任何测试工具都有其应用范围,在不同的软件工程阶段,应该有计划地去使用相应的测试工具,并将测试工具的使用明确定义到公司的开发流程中。
例如,在单元测试阶段,我们应该重点采用白盒测试工具,当软件产品的功能以及用户界面基本确定和逐步实现后,则可以考虑开始使用功能测试工具。集成测试阶段,则可以引入负载压力测试工具,对系统可能承受的负载压力进行测试与评估,并辅以相应的资源,使用监控工具进行故障定位等。
③确定测试重点
对于一些测试项目,尤其是在测试时间有限的情况下,比如,执行一次性能测试,必须能够确定被测项目的主要应用和关键步骤,应对那些质量要求较高并且风险大的部分进行重点测试。
④确定测试目标和指标
针对不同的软件,其软件质量要求的等级和目标是不一样的,通过测试工具可更好地验证系统设计是否达到了预期目标,故在正式开始测试前,应清楚地了解测试的预期目标。
⑤充分利用测试工具的优势
每个测试工具都有自己独特的实现技术,对于同一个测试项目,测试工具可能提供了多种测试方案来供选择,只有充分利用测试工具提供的这些技术,才可能更好、更真实地测试应用系统的实际质量。
⑥加强对测试工程师的技能培训
测试工具的培训是一个长期的过程,并且在实际使用测试工具的过程中,测试工具的使用者可能还存在着多种问题,需要有专家负责解决,否则,对于测试工具使用者的积极性将造成很大的打击。
四、功能自动化测试
1.概述
(1)功能自动化测试工具
①作用
功能自动化测试工具可以帮助测试工程师自动处理测试开发到测试执行的整个过程中的问题。
②主要功能
为了确保应用能够按照预期设计执行而将业务处理过程记录到测试脚本中。当应用被开发完成或应用升级时,测试工具支持测试脚本的编辑、扩展、执行和报告测试结果,并且保证测试脚本的可重复使用,应贯穿于应用的整个生命周期。
(2)注意事项
对于功能测试工具的使用,比较重要的是测试规划问题。如何规划一次录制,使它具有良好的可扩展性、重用性,整个脚本能够有清晰的层次和最大限度地适应以后程序的修改,是在实际工程中用户遇到的最普遍的问题,其实施需要有经验的软件测试人员介入并结合应用来进行具体分析。
2.测试原理
功能自动化测试工具基本上都是采取录制回放的方式来模拟用户的实际操作。当在软件操作中点击图形用户界面上的对象时,测试工具会用一种类C或者其他的脚本语言(TSL)生成测试脚本,该测试脚本记录了操作过程,然后测试工具就可以回放刚才的操作过程。也可以手工编程生成该脚本。通常情况下,测试工具采取以下两种录制模式:
(1)环境判断模式
该模式根据选取的图形用户界面对象,把对软件的操作动作录制下来,并忽略这些对象在屏幕上的物理位置。每次对被测软件进行操作,测试脚本语言会记录并描述所选取的对象和操作动作。当进行录制时,测试工具会对选取的各对象做唯一描述并写入相应的文件中。当软件用户界面发生变化时,只需更新特定的对象记录文件。
环境判断模式的测试脚本非常容易被重复使用。执行测试只需要回放测试脚本。回放时,测试工具从指定文件中读取对象描述,并在被测软件中查找符合这些描述的对象并模拟用户使用鼠标选取该对象、用键盘输入数据的操作。
(2)模拟模式
该模式记录鼠标点击、键盘输入和鼠标在二维平面上(X轴和Y轴)的精确运动轨迹。执行测试时,测试工具让鼠标根据轨迹运动。该模式对需要追踪鼠标运动的测试非常有用。
3.实施测试的操作步骤
不论测试工具采用哪种录制模式,通常,其实施测试必须经历的操作步骤如下:
(1)创建脚本
可以通过录制、编程或两者同用的方式创建测试脚本。测试工具可以自动记录操作并生成所需的脚本代码,还可以直接修改测试脚本以满足各种复杂测试的需求。录制测试时,在需要检查软件反应的地方插入检查点,用来检查GUl对象、位图和数据库。该过程中,测试工具会自动捕捉数据,并将该数据作为期望结果储存下来。
(2)调试脚本
脚本录制或编辑结束后,可先在调试模式下运行脚本,并可以设置中断点(breakpoint)来监测变量,控制对象识别和隔离错误。
(3)执行测试
①概述
脚本调试结束后,便可以在检验模式下测试被测软件。运行测试时,测试工具会自动操作应用程序。此时,测试工具在运行脚本过程中如果遇到了检查点,就把当前数据和事先捕捉并保存的期望值进行比较。如果发现有不符合,就记录下来作为测试结果。
②注意
在具体的测试过程中,为了全面地测试一个应用程序,需要使用不同类型的数据来测试。通常,测试工具都能提供动态数据处理及参数化技术,可以用参数去代替定值,从而真实地反映多个用户行为。
③举例
订单输入的流程。
可能希望把订单号或客户名称作为可变栏,用多套数据进行测试。使用数据驱动向导,订单号或客户名称可以选择用数据表格文件中的相应的栏目的数据进行替换。可以把订单号或客户名称输入数据表格文件,或从其他表格和数据库中导入。数据驱动测试不仅节省了时间和资源,又提高了应用的测试覆盖率。
(4)结果分析
每次测试结束,测试工具都会把测试情况显示在测试结果报告中。测试结果报告会详细描述测试执行过程中发生的所有主要事件,如检查点、错误信息、系统信息或用户信息等。
①若检查点有不符合的情况被发现,可在测试结果窗口查看预期结果和实际测试结果。
②若位图不符合,可查看用于显示预期值和实测结果之间差异的位图。
③若由于测试中发现错误而造成测试运行失败,可直接从测试结果中查看有关错误信息。
五、负载压力自动化测试
1.概述
(1)负载测试
为了证明在与产品(预期)规模等同的数据库中处理给定的事务请求的容量下,系统功能与性能是否与需求规格说明中规定的,可接受的响应时间一致的测试过程。
(2)压力测试
使客户机在大容量情况下运行的测试过程,为了查看应用将在何时何处出现中断,即识别系统的薄弱环节。可能暴露的系统缺陷有内存泄漏、系统资源过量消耗、磁盘空间用完等。
(3)负载压力测试工具
①负载压力测试
对应用进行负载压力测试可以获得重要的基准性能数据,为未来的代码优化、硬件配置以及系统软硬件升级提供方便。负载测试是任何web应用的开发周期中的重要步骤。
②负载压力测试工具
a.该测试工具提供了对Web页面压力测试的完整解决方案,如:用户模拟、Web服务器监控、页面每秒钟点击率统计、单独页面加载时间分析等各种专门针对Web的特性。
b.在测试阶段使用负载压力测试工具进行测试,可以模拟数据库死锁的情况,结合压力分析SQL效率,优化应用程序和数据库配置等,使软件系统更加健壮和高效。
2.测试原理
(1)简介
测试工具都会有后台代理进程,通过该代理进程,测试工具可以监视并获取在各种通信协议下应用系统的客户与服务器端的通信信息,测试工具会用类C或者其他的脚本语言(TSL)生成测试脚本,该脚本记录对服务器的请求过程,然后测试工具就可回放刚才的访问过程,接收服务器的响应,当然也可用手工编程生成该脚本。当被测系统运行时,脚本生成器会自动获取系统客户端与服务器的通信信息并转换成测试工具可以识别的脚本,测试工具通过控制台将测试脚本分发到其他负载生成器上以模拟多用户对服务器的并发访问,同时,控制台还可通过服务器上开启的远程RPC服务,获取相关的资源使用信息,最后可以收集测试数据。
通常情况下,实施负载压力测试的工作示意图如图2-21所示
图2-21 实施负载压力测试的工作示意图
(2)遵循的原则
在进行测试脚本录制与分配的过程中,应遵循以下原则:
①脚本越小越好
如同编写程序代码,不要太长,尽量做到一个功能一个脚本。如果那些功能是连续有序的,必须先做上一个,才能执行下一个,所以必须放在一起。
②选择负载压力最高的业务功能进行测试
由于测试是需要投入时间和金钱的,不可能测试所有的功能。应结合用户实际的使用情况,选择负载压力最高的业务功能进行测试,以满足性能测试的需求,达到测试的预期目的。
③选择所需要的操作进行录制
通过以下途径确定操作是否需要录制:
a.可以找开发人员了解清楚程序设计结构和运行模式;
b.可以靠自己的经验,熟能生巧。
(3)测试工具的并发访问方式
测试工具模拟多用户并发访问有以下两种方式:
①进程回放模式
模拟多进程运行方式,即客户端与服务器的访问采用进程方式,各虚拟用户通过一个进程建立与服务器的通信连接并访问。
②线程回放模式
模拟多线程运行方式,即客户端与服务器的访问采用线程方式,各虚拟用户通过一个线程建立与服务器的通信连接并访问。
(4)测试工具的步骤
无论测试工具采用何种录制回放模式,均须经历以下操作步骤:
①协议选择
测试工具是通过获取在各种通信协议下应用系统的客户端与服务器端的通信信息并进一步来实现负载压力测试的,故首先要确定被测应用系统客户端与服务器端的通信所使用的协议类型。通常,B/S系统选择Web(Http/Html),两层C/S系统则根据C/S结构所用到的后台数据库来选择不同的协议。
②创建测试脚本
选择好相应的录制协议后,就可启动脚本录制工具,通过测试工具的代理进程获取应用系统客户端和服务器端的通信信息,测试工具可自动记录客户端对服务器端的访问操作并自动转换成所需的脚本代码,还可直接编辑测试脚本以满足各种复杂测试的需求。
③参数化测试数据
对于创建的测试脚本,可利用数据池技术对其中的某些数据参数化,从而更好地模拟真实应用访问。
④创建虚拟用户,设定负载方案
由于负载压力测试的目的为模拟多用户并发访问应用系统,所以在开始测试之前应设计好需要模拟的虚拟用户数,然后使用测试工具控制台设定负载方案。
⑤执行测试
设定相应的负载测试方案后,可开始测试,测试过程中,测试工具会自动记录测试结果,包括事务处理的响应时间,服务器的资源占用情况等。
⑥结果分析
测试结束后,测试工具会收集汇总所有的测试数据并生成测试结果报告,这些数据主要包括交易性能数据(如响应时间等)、服务器资源占用情况、网路设备和数据库的实时性能数据等。通过这些数据就可以通过客户端、服务器端以及网络三方面来评估系统组件的运行性能,从而找到应用系统存在的主要问题,为系统改进做准备。