1.4 软件开发与软件测试的联系
1.4.1 软件开发与软件测试各阶段的联系
软件开发模式与软件测试具有密切关系,一般情形下,软件测试与开发各阶段的关系如图1.15所示。
图1.15 软件测试与软件开发过程的关系
(1)项目规划阶段:负责从单元测试到系统测试的整个测试阶段的监控。
(2)需求分析阶段:确定测试需求分析、制定系统测试计划,评审后成为管理项目。其中,测试需求分析是对产品生命周期中测试所需求的资源、配置、每阶段评判通过的规约;系统测试计划则是依据软件的需求规格说明书,制定测试计划和设计相应的测试用例。
(3)详细设计和概要设计阶段:确保集成测试计划和单元测试计划完成。
(4)编码阶段:由开发人员进行自己负责部分的测试代码。在项目较大时,由专人进行编码阶段的测试任务。
(5)测试阶段(单元、集成、系统测试等):依据测试代码进行测试,并提交测试状态报告和测试结果报告。
1.4.2 测试与开发的并行特征
在软件的需求得到确认并通过评审后,概要设计工作和测试计划制定设计工作就要并行进行。如果系统模块已经建立,对各个模块的详细设计、编码、单元测试等工作又可并行。待每个模块完成后,可以进行集成测试、系统测试等,其工作流程如图1.16所示。
图1.16 软件测试与软件开发的并行性
1.4.3 软件测试模型
1.V模型
在软件测试方面,V模型是最广为人知的应用模型,如图1.17所示,尽管很多富有实际经验的测试人员还不太熟悉它。V模型已经存在了很长时间,和瀑布开发模型有着一些共同的特性,是软件开发瀑布模型的变型,主要反映测试活动与分析和设计的关系;强调了在整个软件项目开发中需要经历的若干个测试级别,并与每一个开发级别对应;V模型中的过程从左到右,描述了基本的开发过程和测试行为。V模型的价值在于它非常明确地标明了测试过程中存在的不同级别,并且清楚地描述了这些测试阶段和开发过程期间各阶段的对应关系。
V模型的局限性:把测试作为编码之后的最后一个活动,需求分析等前期产生的错误直到后期的验收测试才能发现;忽略了测试的对象不应该仅仅包括程序,没有明确指出对需求、设计的测试,因此也和瀑布模型一样存在不足。
图1.17 V模型
2.X模型
X模型的基本思想是对测试过程模式进行重新组织,形成“X模型”。X通常代表未知,并包括探索性测试(exploratory testing)的特征。如图1.18所示为X模型示意图。
V模型最主要的不足是无法引导项目的全部过程。一个模型必须能处理开发的所有方面,包括交接,频繁重复的集成,以及需求文档的缺乏等。
X模型的左边描述的是针对单独程序片段所进行的相互分离的编码和测试,此后将进行频繁的交接,通过集成最终合成为可执行的程序(右上半部分),这些可执行程序还需要进行测试。已通过集成测试的成品可以进行封版并提交给用户,也可以作为更大规模和范围内集成的一部分。多根并行的曲线表示变更可以在各部分发生。
由图1.18可见,X模型还定位了探索性测试(右下方),即不进行事先计划的特殊类型的测试,如“这样测一下结果会怎么样?”这一方式帮助有经验的测试人员在测试计划之外发现更多的软件缺陷。
图1.18 X模型
一个模型和一个单独的项目计划有所不同。模型不应该描述每个项目的具体细节,应该对整个项目进行指导和支持。当然,代码的交接也可以简单地认为是一种集成的形式。V模型也并没有限制各种创建周期的发生次数。
应在执行测试之前进行测试设计。X模型包含测试设计的步骤,就像使用不同的测试工具所要包含的步骤一样,而V模型没有这么做。该例提示,X模型在这层意义上看也并不是一个真的模型,取而代之的是,应允许在任何时候选择使用测试设计步骤。
V模型基于一套必须按照一定顺序严格排列的开发步骤,但这很可能并没有反映实际工程过程。尽管很多项目缺乏足够的需求,V模型还是从需求处理开始。V模型提示开发者要对各开发阶段已得到的内容进行测试,但它没有规定要取得多少内容。如果没有任何的需求资料,开发人员知道该做什么吗?在X模型和其他模型中都需要足够的需求并至少进行一次发布。虽然在没有模型的情况下也必须正常工作,但一个有效的模型可以鼓励采用好的实践方法。因此,V模型的一个强项是它明确需求角色的确认,而X模型没有这个机制,这也是X模型的不足之处。
按照V模型所指导的步骤进行工作,而实际某些做法并不切合实用。具有可伸缩性的行为的期望被结合进了X模型,这样,X模型并不要求在创建可执行程序(图1.18中右上方)的一个组成部分的集成测试之前,对每一个程序片段都进行单元测试(图1.18中左侧的行为)。X模型没能提供是否要跳过单元测试的判断准则。X模型填补V模型缺陷,为测试与开发带来明显帮助。
3.H模型
V和X模型的测试过程,都没有很好地体现测试流程的完整性。为解决以上问题,提出了H模型,如图1.19所示。H模型将测试活动完全独立出来,形成一个完全独立的流程,将测试准备活动和测试执行活动清晰地体现出来。
图1.19 H模型
H模型中,软件测试过程活动完全独立,贯穿于整个产品的周期,与其他流程并发地进行,某个测试点准备就绪时,就可以从测试准备阶段进行到测试执行阶段。软件测试可以尽早进行,并且可以根据被测物的不同而分层次进行。如图1.19所示的H模型演示了在整个生产周期中某个层次上的一次测试“微循环”。图中标注的其他流程可以是任意的开发流程,如设计流程或者编码流程。也就是说,只要测试条件成熟了,测试准备活动完成了,测试执行活动就可以进行。
H模型揭示了一个原理:软件测试不仅仅是指测试的执行,还包括很多其他的活动;软件测试是一个独立的流程,贯穿产品整个生命周期,与其他流程并发地进行。H模型指出软件测试要尽早准备,尽早执行。不同的测试活动可以按照某个次序先后进行,但也可能是反复进行,只要某个测试达到准备就绪点,测试执行活动就可以开展。
4.W模型
V模型的局限性在于没有明确地说明早期的测试,无法体现“尽早地和不断地进行软件测试”的原则。在V模型中增加软件各开发阶段应同步进行的测试,演化为基于V&V原理的W模型,如图1.20所示。从模型结构不难看出,开发是“V”模型,测试是与此并行的“V”模型,形成双“V”型,即“W”结构。W模型基于“尽早地和不断地进行软件测试”的原则,在软件的需求和设计阶段的测试活动遵循IEEE1012-1998《软件验证与确认(V&V)》的原则。
图1.20 W模型
W模型由Evolutif公司提出,相对于V模型,W模型更科学。W模型是V模型的发展,强调的是测试伴随着整个软件开发周期,而且测试的对象不仅仅是程序,需求、功能和设计同样要进行测试。测试与开发同步进行,从而有利于尽早地发现问题。
W模型强调测试伴随着整个软件开发周期,而且测试的对象不仅仅是程序,需求、设计等同样需要测试,也就是说,测试和开发是同步进行的。W模型的不足表现在,该模型当中,需求、设计、编码等活动被视为串行的,同时,测试和开发活动也保持着一种线性的前后关系,只有上一阶段完成后,才可以开始下一阶段的活动,因此,这种模式不能支持迭代,也不适应开发过程中的变更调整。
5.前置测试模型
前置测试模型是一个将测试和开发紧密结合的模型,该模型提供灵活的方式,可使项目开发加快速度。前置测试模型可参考图1.21。前置测试模型有以下特点。
图1.21 前置测试模型
(1)开发和测试相结合。前置测试模型将开发和测试的生命周期整合在一起,标识了项目生命周期从开始到结束之间的关键行为,并且表示了这些行为在项目周期中的价值所在。如果其中有些行为没有得到很好的执行,那么项目成功的可能性就会因此而有所降低。如果有业务需求,则系统开发过程将更有效率。在没有业务需求的情况下进行开发和测试是不可能的。而且,业务需求最好在设计和开发之前就被正确定义。
(2)对每一个交付内容进行测试。每一个交付的开发结果都必须通过一定的方式进行测试。源程序代码并不是唯一需要测试的内容。在图中的绿色框表示了其他一些要测试的对象,包括可行性报告、业务需求说明,以及系统设计文档等。这同V模型中开发和测试的对应关系相一致,并且在其基础上有所扩展,变得更为明确。
前置测试模型包括两项测试计划技术。第一项技术是开发基于需求的测试用例。这不仅是为以后提交上来的程序的测试做好初始化准备,也是为了验证需求是否是可测试的。这些测试可交由用户来进行验收测试,或由开发部门做某些技术测试。许多测试组织都认为,需求的可测试性即使不是需求首要属性,也应是其最基本的属性之一。因此,在必要时可为每一个需求编写测试用例。基于需求的测试最多也只是和需求本身一样重要。一项需求可能本身是错误的,但它仍是可测试的。但前置测试无法为一些被忽略的需求来编写测试用例。
第二项技术是定义验收标准。在接收交付的系统之前,用户需要用验收标准来进行验证。但验收标准并不仅为定义需求,还应在前置测试之前进行定义,这将帮助揭示某些需求是否正确,以及某些需求是否被忽略了。
同样地,系统设计在投入编码实现之前也必须经过测试,以确保其正确性和完整性。很多组织趋向于对设计进行测试,而不是对需求进行测试。在对设计进行的测试中有一项非常有用的技术,即制订计划以确定应如何针对提交的系统进行测试,这在处于设计阶段并即将进入编码阶段时十分有用。
(3)在设计阶段进行计划和测试设计。设计阶段是做测试计划和测试设计的最好时机。很多组织要么根本不做测试计划和测试设计,要么在即将开始执行测试之前才仓促地完成测试计划和设计。在这种情况下,测试只是验证了程序的正确性,而不是验证整个系统本该实现的设计思路。
在V模型中,验收测试最早被定义好,并在最后执行,以验证所交付的系统是否真正符合用户业务的需求。与V模型不同的是,前置测试模型认识到验收测试中所包含的3种成分,其中的2种都与业务需求定义相联系,即定义基于需求的测试,以及定义验收标准。但是,第三种则需要等到系统设计完成,因为验收测试计划是由针对按设计实现的系统来进行的一些明确操作定义所组成的,这些定义包括:如何判断验收标准已经达到,以及基于需求的测试已算成功完成。
技术测试主要是针对开发代码的测试,例如,V模型中所定义的动态的单元测试、集成测试和系统测试。另外,前置测试还提示我们应增加静态审查,以及独立的QA测试。QA测试通常跟随在系统测试之后,从技术部门的意见和用户的预期方面出发,进行最后的检查。同样还有特别测试,这些测试包括负载测试、安全性测试、可用性测试等,这些测试不是由业务逻辑和应用进行驱动的。
对技术测试最基本的要求是验证代码的编写和设计的要求是否相一致。一致的意思是系统确实提供了要求提供的,并且系统并没有提供不要求提供的。技术测试在设计阶段进行计划和设计,并在开发阶段由技术部门来执行。
(4)测试和开发结合在一起。前置测试将测试执行和开发结合在一起,并在开发阶段以编码-测试-编码-测试的方式来体现。也就是说,程序片段一旦编写完成,就会立即进行测试。普通情况下,先进行的测试是单元测试,因为开发人员认为通过测试来发现错误是最经济的方式。但也可参考X模型,即一个程序片段也需要相关的集成测试,甚至有时还需要一些特殊测试。对于一个特定的程序片段,其测试的顺序可以按照V模型的规定,但其中还会交织一些程序片段的开发,而不是按阶段完全地隔离。
在技术测试计划中必须定义好这样的结合。测试的主体方法和结构应在设计阶段定义完成,并在开发阶段进行补充和升版。这尤其会对基于代码的测试产生影响,这种测试主要包括针对单元的测试和集成测试。不管在哪种情况下,如果在执行测试之前做一点计划和设计,都会提高测试效率,改善测试结果,而且对测试重用也更加有利。
(5)让验收测试和技术测试保持相互独立。验收测试应该独立于技术测试,这样可以提供双重的保险,以保证设计及程序编码能够符合最终用户的需求。验收测试既可以在实施阶段的第一步来执行,也可以在开发阶段的最后一步执行。
前置测试模型提倡验收测试和技术测试沿两条不同路线进行,每条路线分别地验证系统是否能够如预期的设想进行正常工作。这样,当单独设计好的验收测试完成了系统的验证,即可确信这是一个正确的系统。
(6)反复交替的开发和测试。在项目中从很多方面可以看到变更的发生,例如,需要重新访问前一阶段的内容,或者跟踪并纠正以前提交的内容,修复错误,排除多余的成分,以及增加新发现的功能,等等。开发和测试需要一起反复交替地执行。模型并没有明确指出参与的系统部分的大小。这一点和V模型中所提供的内容相似。不同的是,前置测试模型对反复和交替描述得非常明确。
(7)发现内在的价值。前置测试为需要使用测试技术的开发人员、测试人员、项目经理和用户等带来不同于传统方法的内在价值。与以前方法中很少划分优先级所不同,前置测试用较低的成本来及早发现错误,并且充分强调了测试对确保系统的高质量的重要意义。前置测试代表了整个对测试的新的不同观念。在整个开发过程中,反复使用了各种测试技术以使开发人员、经理和用户节省其时间,简化其工作。
通常情况下,开发人员会将测试工作视为阻碍其按期完成开发进度的额外负担。然而,当提前定义好该如何对程序进行测试以后,会发现开发人员将节省至少20%的时间。虽然开发人员很少意识到他们的时间是如何分配的,也许他们只是感觉到有一大块时间从重新修改中节省下来可用来进行其他开发。保守地估算,在编码之前对设计进行测试可以节省总共将近一半的时间,这可以从以下方面体现出来:
针对设计的测试编写是检验设计的一个非常好的方法,由此可以及时避免因为设计不正确而造成的重复开发及代码修改。通常情况下,这样的测试可以使设计中的逻辑缺陷凸显出来。另一方面,编写测试用例还能揭示设计中比较模糊的地方。总体来说,如果确定了如何对程序进行测试,那么程序员就能确定他们所开发的程序怎样才算正确。
测试工作先于程序开发而进行,这样可以明显地看到程序应该如何工作,否则,如果要等到程序开发完成后才开始测试,那么测试只是查验开发人员的代码是如何运行的。而提前的测试可以帮助开发人员立刻得到正确的错误定位。在测试先于编码的情况下,开发人员可以在一完成编码时就立刻进行测试,而且更有效率,在同一时间内能够执行更多的现成的测试。
6.敏捷开发的测试
在敏捷开发中,软件测试是整个软件项目的“指引灯”,引领软件开发的过程。软件测试人员为项目组提供各种信息,使项目开发过程基于这些信息做出正确的决定。敏捷开发过程的软件测试作用如图1.22所示。
图1.22 敏捷开发中的软件测试作用
在敏捷项目中,测试人员不是质量保证的唯一,而是整个项目组的每一个人都要对质量负责。测试不再做出发布的决定。测试人员主要责任之一是帮助开发人员找到目标。在敏捷开发中,如果测试者在团队中采用完全的XP方法,则要遵循敏捷的原则,调整个人的角色,成为真正的敏捷测试员。在敏捷团队中,测试的核心工作内容依然是不断地寻找缺陷,这时测试需要着重考虑以下几点:①更多采用探索性的测试方法;②更多采用上下文驱动的测试方法;③更多采用敏捷自动化测试原则。
在敏捷项目开发中,测试者不完全依赖文档,需要自动地寻找和挖掘更多关于软件(程序)的信息来指导测试。探索性的测试强调设计、测试和学习被测系统的测试方法,并能够被充分借鉴和应用。敏捷的本质之一是强调合作,在敏捷项目中测试人员需要主动和开发人员讨论软件(程序)的需求和设计,研究缺陷的出现原因。
敏捷测试需要持续地测试、不断地回归测试和快速地测试。