1.2.1 软件开发生命周期模型
为了使软件开发的工作系统化,并且可控制,需要采用软件开发生命周期模型和开发过程来管理所有的活动。软件开发生命周期模型有多种,例如:瀑布模型、V-模型、螺旋模型以及其他各类增量迭代模型,还有目前流行的“敏捷”或者“轻量级”方法。所有这些模型都定义了一种系统化的方式,以达到工程项目中工作的有序化。
在多数情况下,软件开发生命周期模型定义了软件开发过程的各个工作阶段和步骤,它们完成后将以文档或代码的形式呈现。一个阶段的完成,通常被称为一个里程碑。里程碑的实现是指完成了需要的交付物,并且与要求的质量标准保持一致。通常,在软件开发中需要定义专注于特定任务的角色。有时候,除了模型之外,在特定阶段用到的技术和过程也需要描述。使用模型有助于资源计划(例如:时间、人员、基础设施等)的细化。在软件工程中,软件开发生命周期模型定义了参与项目的每个人需要完成的任务,以及完成这些任务的时间顺序。
测试不是孤立存在的,它是各种软件开发生命周期模型中的重要组成部分,测试活动与开发活动是息息相关的。不同的软件开发生命周期模型定义了不同的测试阶段、测试活动和测试方法。下面介绍一些常见的软件开发生命周期模型。
1.2.1.1 顺序模型
1.瀑布模型(Waterfall Mode)
瀑布模型最早由Winston W.Royce在1970年提出,在软件工程中占有重要的地位,它提供了软件开发的基本框架。从测试的角度而言,瀑布模型最大的缺点是,测试是软件开发过程中的一个阶段,测试被看做是对软件产品的最终检查,类似于制造业中将产品交付给客户之前的检查。
图1-1显示了一个传统的瀑布模型,它将软件开发生命周期划分为系统需求(System Requirement)、软件需求(Software Requirement)、分析(Analysis)、程序设计(Program Design)、编码(Coding)、测试(Testing)和运行(Operations)七个基本阶段,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。从本质来说,它是一个软件开发架构,其开发过程是通过一系列阶段顺序地展开的,只有当一个开发阶段完成后,下一个开发阶段才会开始。
图1-1 瀑布模型
尽管瀑布模型由于存在一些缺点而招致很多的批评,但是它对很多类型的项目而言依然是有效的。如果能够正确使用瀑布模型,可以节省大量的时间和金钱。是否采用瀑布模型,主要取决于是否能够充分理解客户的需求,以及在项目开发过程中是否经常发生需求变更。对于需求经常发生变更的项目,采用瀑布模型是不合适的,这时候就需要考虑其他类型的软件开发生命周期模型。
2.V模型(V-Mode)
V模型是瀑布模型的变种,它体现的主要思想是:开发任务和测试任务是相互对等的活动且同等重要。V模型的左右两侧组成字母V的两个边,形象地体现了这一点。V模型的左侧代表软件开发过程,在软件开发过程中,系统是逐步设计完善的,编码是最后一步。V模型的右侧描述了集成和测试的过程,通过不断组合程序组件,形成更大的子系统(集成),并对它们的功能和非功能进行测试。根据这个模型,开发得到的整个系统将以验收测试作为系统集成和测试活动的结束点。
图1-2显示了由开发活动和测试活动共同组成的一个V模型,V模型主要的开发活动有需求规格说明、系统功能设计、系统技术设计、组件规格说明和编码,相应的测试级别有组件测试、集成测试、系统测试和验收测试。其中,构成V模型左侧的活动就是人们熟知的瀑布模型中的活动。
图1-2 通用V模型
● 需求规格说明:从客户或将来的系统用户中收集,并对它们进行详细描述,最终得到批准的要求和需求。需求规格说明定义了开发系统的目的和需要实现的特性和功能。
● 系统功能设计:将需求映射到系统的功能和框图上。
● 系统技术设计:设计系统的具体实现方式。这个阶段包括定义系统环境的接口,同时将整个系统分解成更小且容易理解的子系统(系统架构),从而可以对每个子系统进行独立的开发。
● 组件规格说明:定义每个子系统的任务、行为、内部结构以及与其他子系统的接口。
● 编码:通过编程语言实现所有已经定义的组件(例如:模块、单元、类)。
在V模型中,随着整个构建阶段的深入,对软件系统的描述越来越详细。通常来说,在某个构建中引入的错误最容易在本构建阶段中发现。因而,对于每个构建阶段, V模型的右边定义了相应的测试级别。在每个测试级别都要检查开发的输出是否满足具体的要求,或者是否满足这些特定阶段相关的要求。
● 组件测试:验证软件组件是否按照组件规格说明(详细设计说明)正确执行,即保证每个最小的单元能够正常运行。组件测试一般由开发人员来执行,首先设定最小的测试单元,然后通过设计相应的测试用例来验证各个组件功能的正确性。
● 集成测试:检查多个组件是否按照系统技术设计描述的方式协同工作。集成测试的主要关注点是系统能够成功编译,实现了主要的业务功能,系统各个模块之间的数据能够正常通信等。
● 系统测试:验证整个系统是否满足需求规格说明。
● 验收测试:从用户的角度检查系统是否满足合同中定义的需求或者用户需求。
3.W模型(W-Mode)
V模型存在一定的局限性,它仅仅把测试作为开发之后的活动。因此,V模型无法说明早期测试的重要性,也无法体现尽早进行软件测试的这个原则。通过在V模型中增加软件各开发阶段同步进行的测试活动,V模型被演化为W模型,如图1-3所示。在W模型中开发是“V”,测试也是与此相重叠的“V”。W模型体现了“尽早地和不断地进行软件测试”的原则,在软件的需求和设计阶段已经开始测试活动。
与V模型相比,W模型可以说是前者自然而然的发展和演化,由Evolutif公司在1999年提出。W模型增加了软件各开发阶段中应同步进行的测试活动,如图1-3所示。W模型由两个V模型组成,分别代表测试与开发过程,图中明确表示出了测试与开发的并行关系。
图1-3 W模型
W模型强调:测试贯穿于整个软件开发生命周期,而且测试的对象不仅仅是程序,需求和设计规格说明等软件工作产品同样需要测试,也就是说,测试与开发是同步进行的。W模型有利于尽早地、全面地发现问题,例如:测试人员应该参与到对需求的测试活动中,以尽早发现其中的缺陷。同时,对需求的测试也有利于及时了解项目难度和测试风险,及早制定应对措施,这将显著减少总体测试时间,加快项目进度。
但W模型也存在局限性。在W模型中,需求、设计、编码等活动被视为串行的,上一阶段完全结束,才可正式开始下一个阶段工作。因此,对于当前软件开发复杂多变的情况,W模型并不能完全解决测试管理面临的困惑。
1.2.1.2 增量迭代模型
前面描述了顺序开发模型(瀑布模型、V模型和W模型),这些模型的一个重要特点是所有的活动是顺序的。顺序开发模型成功使用的一个前提是软件系统具备完善、明确的需求。但是随着软件开发的不断发展,顺序模型越来越无法满足需要。人们很难在项目开始的时候就进行完善的需求分析和设计,这就导致在顺序模型下,要不断地进行返工,对以前的需求、设计或编码进行修改。为了解决顺序模型的这些不足,出现了增量迭代模型。增量迭代模型具有以下特点:
● 允许需求的变化。需求的不断变更一直是项目延期交付、令客户不满意和打击开发人员士气的主要原因。为了解决这些问题,使用增量迭代模型的团队应该在项目开发的前期就关注生成和演示可执行的软件,这样就得进行强制的需求检查,优先实现重要的和稳定的需求。
● 集成不是在项目后期进行的“大动作”。将系统的集成留到项目的后期,几乎总是会导致耗时的返工(有时这种返工甚至花费了整个项目工作量40%的时间)。为了避免这种返工,每一次迭代都以集成构建系统各部分结束,这样不断地集成将最小化日后的返工。
● 早期的迭代可以降低风险。采用增量迭代模型可以帮助团队在早期的迭代中降低风险,因为在这些迭代中包括了对所有中间组件的测试。当早期的迭代覆盖了项目的很多方面时(例如:工具、购买的软件和团队成员的技能等),团队很快能够发现相关风险是否是真实的,并且能够在问题的萌芽阶段揭示没有被发现的新风险。
● 对产品的管理能够采取战术性的变化。采用增量迭代模型可以使得团队快速生成可执行的架构(虽然功能有限)。为了应对竞争对手的快速版本发布,这个架构能够快速地调整产品,使之成为“轻量级”或者“改进型”版本。
● 重用更加容易。识别在迭代中进行的部分设计和实现的公用部分要比在计划期间找出公用部分更加容易。早期的设计评审允许系统架构人员发现潜在的可重用的机会,并且利用这个机会为接下来的迭代开发成熟的公用代码。
● 在每一个迭代中发现并更正缺陷。采用增量迭代模型可以生成健壮的架构和高质量的应用,甚至能够在早期的迭代中(而不是在项目末期的大规模测试阶段)发现缺陷。因此,能够在性能瓶颈没有破坏项目的计划之前发现它。
● 更好地利用项目的人力资源。很多开发组织使用一种管道式的组织方式,来匹配他们的瀑布开发模型:分析人员将完成的需求发送给设计人员,设计人员将完成的设计发送给开发编程人员,编程人员再将他们开发的组件发送给集成人员,集成人员将组件集成起来发送给测试人员测试。这种多次的传递不仅容易产生错误,而且容易造成误解,这种方式也会使人们对最终的产品缺少责任感。迭代开发过程鼓励团队成员更加广泛地参与项目的各个环节,允许团队成员扮演多种角色。因此,项目经理能够更好地利用项目人员,并可以消除有风险的传递。
● 团队成员技能得到不断提高。工作在增量迭代开发的项目中的团队成员,在软件开发生命周期内有很多机会从他们所犯的错误中吸取教训,并能够从一个增量迭代到另一个增量迭代的过程中改进他们的技能。通过评估每个增量迭代,项目经理能够为团队成员发现培训的机会。相反,工作在瀑布模型中的团队成员被限制在狭窄的技术专长上,并且仅仅有机会从事设计、编码或者测试中某一方面的工作。
● 不断改进开发过程。增量迭代末尾的评估不仅能够从产品或者计划方面揭示项目的状态,也可以帮助项目经理分析在下一个增量迭代中如何改进项目的组织结构和开发过程。
常见的增量迭代模型包括螺旋模型、RUP(Rational Unified Process)和敏捷开发,下面分别阐述这三种增量迭代模型。
1.螺旋模型
螺旋模型由Barry W.Boehm于1988年提出。螺旋模型是增量迭代开发模型的一种,如图1-4所示,它兼顾了快速原型迭代的特征以及瀑布模型的系统化与严格监控。螺旋模型最大的特点在于引入了其他模型不具备的风险分析,使软件在无法排除重大风险时有机会停止,以减小损失。在每个迭代阶段构建原型是螺旋模型用以减小风险的途径。螺旋模型更适合大型的系统级的软件应用。
图1-4 螺旋模型
螺旋模型中一个典型的迭代包括以下步骤:
① 明确本次迭代的目标、备选方案以及应用备选方案的限制。
② 对备选方案进行评估,明确并解决存在的风险,建立原型。
③ 当风险得到很好的评估与解决后,应用瀑布模型进行本次迭代的开发与测试。
④ 对下一迭代进行计划与部署。
⑤ 项目利益相关者对本次迭代的交付物进行评审,同时检查下一阶段的计划。
螺旋模型的优点是它在引入风险驱动方法的同时,兼顾了原型开发和瀑布模型等开发模型的优点。在一定条件下,螺旋模型能够演变成其他的开发模型,例如:如果项目获得错误的用户接口或无法满足性能需求等方面的风险很低,同时,它在控制成本和进度方面的风险很高的情况,螺旋模型将会演化成瀑布模型。除了这个优点以外,螺旋模型还具有以下优点:
● 可以在项目前期考虑对已经存在的软件进行重用。
● 在软件产品开发过程中考虑了软件质量目标。
● 关注于缺陷预防,并能够尽早地发现缺陷。
● 更好地控制项目活动的资源和相关成本。
螺旋模型在很多领域得到了广泛的引用,但是它也存在一定的不足,包括:
● 过分依赖风险评估,一旦在风险管理过程中出现偏差,将造成重大损失。
● 过于灵活的开发过程不适合开发者和客户之间有明确合同约定的情况。
● 该模型本身的文档化和推广需要大量的工作量。
2.RUP
RUP 是由 IBM 开发和维护的过程产品。RUP 的开发团队与顾客、合作伙伴、Rational 产品小组及顾问公司共同协作,确保开发过程持续地更新和提高,以反映新的经验和不断演化的实践经验。
图1-5显示了RUP的整体架构,整个开发过程可以用二维结构来表达。
图1-5 RUP
● 横轴代表了制定开发过程时的时间,体现了过程的动态结构。
● 纵轴表示九个核心工作流程,代表了所有角色和活动的逻辑分组情况。
RUP将软件开发生命周期划分为四个连续的阶段。
● 初始阶段(Inception):初始阶段的目标是为系统建立商业案例和确定项目的边界。为了达到该目标,必须识别所有与系统交互的外部实体,在较高层次上定义交互的特性。它包括识别所有的用例和描述一些重要的用例。商业案例包括验收规范、风险评估、所需资源估计、体现主要里程碑日期的阶段计划等。
● 精化阶段(Elaboration):精化阶段的目标是分析问题领域,建立健全的体系结构基础,编制项目计划,淘汰项目中最高风险的元素。体系结构的决策必须在理解整个系统的基础上做出,诸如理解系统的范围、主要功能和非功能需求等。
● 构建阶段(Construction):在构建阶段,所有涉及的构件和应用程序功能被开发并集成为产品,并详尽测试所有的功能。从某种意义上说,构建阶段的重点在管理资源和控制运作以优化成本、进度和质量。
● 产品化阶段(Transition):产品化阶段的目标是将软件产品交付给用户群体。当产品成熟得足够发布到最终用户时,就进入了产品化阶段。产品发布给最终用户后,从用户现场可能会反馈各种各样的问题。因此,需要纠正用户使用产品过程中出现的问题或开发新版本等。
RUP描述了如何为软件开发团队有效地部署经过商业化验证的软件开发方法,即最佳实践。它们被称为最佳实践,不仅仅是因为可以精确地量化它们的价值,而且它们也被许多成功的机构普遍地运用。这些最佳实践是:迭代的开发软件、需求管理、使用基于构件的体系结构、可视化软件建模、验证软件质量和控制软件变更。同时RUP为使整个团队有效地利用最佳实践,还为每个团队成员提供了必要的准则、模板和工具指导。
3.敏捷开发
2001年初,由于看到许多公司的软件团队陷入了不断增长的软件开发过程的泥潭,一批业界专家聚集在一起,概括出了一些可以让软件开发团队具有快速工作、响应变化能力的价值观(Value)和原则(Principle)。他们称自己为敏捷(Agile)联盟。在随后的几个月中,他们创建出了一份价值观声明,也就是敏捷联盟宣言(The Manifesto of the Agile Alliance)。
敏捷软件开发宣言:
我们正在通过亲身实践以及帮助他人实践,揭示更好的软件开发方法。通过这项工作,我们认为:
● 个体和交互 胜过 过程和工具。
● 可以工作的软件 胜过 面面俱到的文档。
● 客户合作 胜过 合同谈判。
● 响应变化 胜过 遵循计划。
虽然右项也有价值,但是我们认为左项具有更大的价值。
Kent Beck James Grenning Robert C. Martin
Mike Beedle Jim Highsmith Steve Mellor
Arie van Bennekum Andrew Hunt Ken Schwaber
Alistair Cockburn Ron Jeffries Jeff Sutherland
Ward Cunningham Jon Kern Dave Thomas
Martin Fowler Brian Marick
从上述的价值观中引出了下面的12条原则,它们是敏捷开发区别于其他过程的特征所在:
● 最优先要做的是通过尽早地、持续地交付有价值的软件来使客户满意。
● 即使到了开发的后期,也欢迎需求的变更。敏捷开发利用变化为客户创造竞争优势。
● 不断地交付可以工作的软件,交付的间隔可以从几周到几个月,交付的时间间隔越短越好。
● 在整个项目开发生命周期,业务人员和开发人员必须天天都在一起工作。
● 围绕被激励起来的个人来构建项目,给他们提供所需要的环境和支持,并且信任他们能够完成工作。
● 在团队内部,最具有效果并且富有效率的传递信息的方法就是面对面的交谈。
● 能够工作的软件是首要的进度度量标准。
● 敏捷开发提倡可持续的开发速度。责任人、开发者和用户应该能够保持一个长期的、恒定的开发速度。
● 简单是根本。
● 不断地关注优秀的技能和好的设计会增强敏捷能力。
● 最好的构架、需求和设计出自于自组织的团队。
● 每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。
业界流行的敏捷开发方法多种多样,因此,需要根据项目大小和性质选择合适的敏捷开发方法,例如:极限编程 XP(eXtreme Programming)更加适合小型项目3~5人的团队,Scrum、DSDM(Dynamic Systems Development Methodology)等更加适合大型团队的项目开发。但是,敏捷开发也不是一成不变放之四海皆准的准则,而是一个方法的最佳实践。各个团体和组织也需要不断地定制自己的最佳实践。
1.2.1.3 模型中的测试
前面描述了一些常见的软件开发生命周期模型,而测试是其中的重要组成部分。对于测试而言,不管采用何种软件开发生命周期模型,一个好的测试都应该具有以下特点:
● 每个开发活动都有对应的测试活动。
● 每个测试级别都有其特有的测试目标。
对于每个测试级别,需要在对应的开发活动过程中进行相应的测试分析和设计。在软件开发生命周期中,测试人员在软件工作产品处于初稿阶段就应该参与它们的评审。根据项目的特征或系统的架构,可以对测试级别进行合并或重新组合,例如:系统集成测试。在V模型中,适合系统测试的基本测试过程可以描述如下:
① 系统测试计划与项目计划同时进行,测试控制将持续到系统测试结束阶段完成。
② 系统测试分析与设计也与需求分析、系统和架构设计(高层次的)等同时进行。
③ 系统测试环境(例如:测试台、测试装置)的部署应在系统测试分析和设计阶段就开始,并一直持续到系统测试执行开始之前(尽管大部分测试环境部署工作应与编码和组件测试同期进行)。
④ 满足系统测试的入口准则之后开始系统测试执行。系统测试的入口准则通常至少要求已经完成组件测试以及组件之间的集成测试。系统测试的执行会一直持续到满足系统测试的出口准则。
⑤ 对系统测试的出口准则的评估和系统测试结果的报告应在测试执行的整个过程中不断进行,通常在项目截止日期到来前会加大评估的频率。
⑥ 满足系统测试的出口准则,并且进行了相应的测试结束活动(例如:系统测试经验总结)之后,系统测试得以结束。在实际测试过程中,这些活动常常被推迟到验收测试之后或者整个项目活动结束之后才进行。
对于商业现货软件(COTS)产品的系统集成,购买者可能会在系统级别进行集成测试(例如:与基础设施集成测试、和其他系统的集成测试或系统的商业部署等)和验收测试(例如:功能测试/非功能测试、用户操作测试等)。