CTFL(二)贯穿软件开发生存周期中的测试
贯穿软件开发生存周期中的测试
验收测试(acceptance testing),黑盒测试(black-box testing),组件集成测试(component integration testing),组件测试(component testing),确认测试(confirmation testing),功 能测试(functional testing),集成测试(integration testing),维护测试(maintenance testing),非功能测试(non-functional testing),回归测试(regression testing),左移 (shift-left),系统集成测试(system integration testing),系统测试(system testing),测 试级别(test level),测试对象(test object),测试类型(test type),白盒测试(white-box testing)。
软件开发生存周期中的测试
软件开发生存周期(SDLC)模型是对软件开发过程的抽象、概要表述。SDLC 模型定义了软件开发过程中不同开发阶段和活动类型之间的逻辑和时间关系。SDLC 模型的示例包括:顺序开发模型(例如瀑布模型、V 模型)、迭代开发模型(例如螺旋模型、原型模型)和增量开发模型(例如统一软件开发过 程)。
软件开发过程中的活动也可以通过更详细的软件开发方法和敏捷实践来描述。例如:验收测试驱动开发(ATDD)、行为驱动开发(BDD)、领域驱动设计(DDD)、极限编程(XP)、特征驱动开发 (FDD)、看板、精益管理、Scrum 和测试驱动开发(TDD)。
软件开发生存周期对测试的影响
测试必须适应软件开发生存周期才能成功。软件开发生存周期的选择会对以下几个方面产生影响:
- 测试活动的范围和时间安排(例如测试级别和测试类型)。
- 测试文档的详细程度。
- 测试技术和测试方法的选择。
- 测试自动化程度。
- 测试人员的角色和职责。
在顺序开发模型中,测试人员通常在软件开发的初期阶段参与需求评审、测试分析和测试设计。可执行代码通常在后期阶段创建,因此通常无法在软件开发生存周期早期进行动态测试。
在某些迭代和增量开发模型中,每次迭代都会提供可工作的增量原型或产品。也就是说在每个迭代 中,静态和动态测试都可以在所有测试级别上执行。频繁的增量交付需要快速反馈和全面回归测试。
敏捷软件开发假定在项目过程中都可能发生变化。因此,在敏捷项目中,更倾向于轻量级的工作产 品文档和全面测试自动化,以便更容易进行回归测试。此外,大部分人工测试往往使用基于经验的测试技术(参阅第 4.4 节),不需要事前进行大量的测试分析和设计。
软件开发生存周期与良好的测试实践
无论选择哪种软件开发生存周期模型,良好的测试实践包括以下内容:
-
每个软件开发活动,都有相应的测试活动,以便对所有开发活动进行质量控制。
-
不同测试级别(参阅第 2.2.1 章)具有特定且不同的测试目标,可以确保测试既全面又避免冗余。
-
给定测试级别的测试分析和设计始于相应的软件开发生存周期开发阶段,以便测试能够遵循早 期测试的原则(参阅第 1.3 节)。
-
相关文档的初稿完成时,测试人员立即参与评审工作产品,以便早期测试和缺陷检测,从而支持测试左移方法(参阅第 2.1.5 节)。
测试是软件开发的驱动
测试驱动开发(TDD)、验收测试驱动开发(ATDD)和行为驱动开发(BDD)是类似的开发方法,将测试定义为指导开发的手段。这些方法都实现了早期测试的原则(参阅第 1.3 节)并遵循左移方法(参 阅第 2.1.5 节),因为测试在编写代码之前定义。它们支持迭代开发模型。这些方法的具体特点如下:
- 测试驱动开发(TDD):
- 通过测试用例来指导编码(而不是详尽的软件设计)(Beck 2003)。
- 先编写测试,后编写代码以满足测试,最后对测试和代码进行重构。
- 验收测试驱动开发(ATDD)(参阅第 4.5.3 节):
- 作为系统设计过程的一部分,从验收准则中导出测试(Gärtner 2011)。
- 在部分应用程序开发前,编写测试,以满足测试的要求。
- 行为驱动开发(BDD):
- 用简化的自然语言编写测试用例来表达应用程序的期望行为,利益相关方容易理解,通常使用 Given/When/Then 格式(Chelimsky 2010)。
- 自动将测试用例转化为可执行的测试。
对于上述所有方法,通常应用自动化测试,以确保将来改写或重构的代码质量。
DevOps与测试
DevOps 是一种组织方法,旨在通过使开发(包括测试)和运维部门共同努力,实现一系列通用目标,从而实现协同效应。DevOps 要求组织内部进行文化转变,将开发和运维的职能同等看待,以弥合开发(包括测试)和运维之间的差距。DevOps 提倡团队的自主权、快速反馈、集成工具链以及持续集成 (CI)和持续交付(CD)等技术实践。通过 DevOps 交付流水线,软件团队可以更快地构建、测试和发 布高质量的代码(Kim 2016)。
从测试的角度来看,DevOps 的好处包括:
- 代码质量的快速反馈,并判断变更是否对现有代码产生不利影响。
- 持续集成(CI)通过鼓励开发人员提交高质量的代码,并辅以组件测试和静态分析,在测试中实现左移方法(参阅第 2.1.5 节)。
- 促进 CI/CD 自动化过程,有助于建立稳定的测试环境。
- 更加关注非功能性质量特性(例如性能、可靠性)。
- 交付流水线的自动化,减少人工重复测试的需求。
- 由于自动化回归测试的规模和范围,降低了回归风险。
然而,DevOps 也面临着某些风险和挑战,包括:
- 必须定义和建立 DevOps 交付流水线。
- 必须引入和维护 CI/CD 工具。
- 测试自动化需要额外资源,这些资源可能难以建立和维护。
尽管 DevOps 提供了高度自动化测试,但从用户的角度来说,仍然需要人工测试。
左移的方法
测试早期介入的原则(参阅第 1.3 节)有时被称为“左移”,这是软件开发生存周期中较早进行测 试的方法。左移建议测试应该早期进行(例如,代码实现或组件集成前开始测试),但不能因此忽视软件开发生存周期的后期测试。
许多良好的实践可以说明如何实现测试 “左移”,包括:
- 从测试的角度评审规格说明。对规格说明进行评审通常可以发现潜在的缺陷,例如规格说明表述模糊、不完整和不一致。
- 编码之前编写测试用例,在代码实现过程中通过测试用具(test harness)运行代码。
- 使用持续集成(CI)和持续交付(CD),提供快速反馈和自动化组件测试,可以在代码提交到代码库时运行源代码测试。
- 在动态测试之前或作为自动化过程的一部分对源代码进行静态分析。
- 在可能的情况下,从组件测试级别开始进行非功能性测试。这是左移形式之一,因为非功能性测试类型通常在系统完整且代表性的测试环境就绪后,在软件开发生存周期的后期执行。
左移方法可能会在过程早期增加培训、工作量和成本,但可以节省过程后期的工作量和成本。 对于左移,重要的是让利益相关方相信并接受此种方法。
回顾与过程改进
回顾会议(也称为“项目总结会议/post-project meetings”和项目回顾)作为发布的里程碑,通常在项目或迭代结束后,按需召开。回顾会议的时间和组织方式取决于所采用的特定软件开发生存周期模型。回顾会议上,参与者(不仅限于测试人员,还包括开发人员、架构师、产品负责人、业务分析师等)讨论以下内容:
- 哪些工作是成功的,应予以保留?
- 哪些工作没成功,可以改进?
- 如何整合改进并保持未来成功?
应记录结果,通常作为测试完成报告的一部分(参阅第 5.3.2 节)。回顾对于成功实施持续改进至关重要,对任何建议的改进都要进行跟踪。
测试的典型收益包括:
- 增加测试的有效性/效率(例如,实施过程改进的建议)。
- 提高测试件的质量(例如,联合评审测试过程)。
- 团队凝聚力和学习能力(例如,提出问题,列出改进点)。
- 提高测试依据的质量(例如,处理和解决需求范围和质量方面的缺陷)。
- 改善开发和测试之间的合作(例如,定期评审和优化协作)。
测试级别和测试类型
测试级别是共同组织和管理的测试活动组。每个测试级别都是测试过程的一个实例,在给定的开发阶段,从单个组件到完整系统,或在适用情况下,乃至到系统的系统(systems of systems),执行软件相关的测试过程。
测试级别与软件开发生存周期内的其他活动相关。在顺序 SDLC 模型中,测试级别通常定义为:一 个级别的出口准则是下一个级别的入口准则的一部分。在一些迭代开发模型中,这可能不适用。开发活动可能跨越多个测试级别。测试级别在时间上可能重叠。
测试类型,是与某种质量特性相关的测试活动的集合,这些测试活动中的大部分可以在每个测试级别进行。
测试级别
在本课程大纲中,将列举描述下列五个测试级别:
- 组件测试(也称为单元测试),侧重于对单独组件的测试。组件测试通常需要一些特殊的支 持,例如需要使用测试用具或者单元测试框架。组件测试通常由开发人员在他们的开发环境中 进行。
- 组件集成测试(也称为单元集成测试),侧重于对组件之间的接口及交互进行测试。组件集成 测试重度依赖于集成策略方法,例如,自底向上集成,自顶向下集成或者大爆炸集成。
- 系统测试,关注于对整个系统或产品的总体行为和能力,通常包含覆盖“端到端业务”的功能 测试以及针对非功能质量特性的测试。对于一些非功能质量特性的测试,更倾向于一个完整系统,在具有代表性的测试环境中进行测试,例如,易用性测试。使用模拟的子系统也是可能的。系统测试可以由独立测试团队执行,并且与系统规格说明有关。
- 系统集成测试,侧重于对被测系统与其他系统以及外部服务的接口的测试。系统集成测试需要 合适的测试环境,最好是与运行环境类似的测试环境。
- 验收测试,侧重于确认和展示部署准备情况,这意味着系统满足了用户的业务要求。在理想情 况下,验收测试应该由潜在用户执行。验收测试的主要形式有:用户验收测试(UAT)、运行 验收测试、合同验收测试以及法规验收测试、Alpha 测试和 Beta 测试。
测试级别可以通过以下(非详尽)属性列表来区分,以避免测试活动的重叠:
- 测试对象
- 测试目的
- 测试依据
- 缺陷和失效
- 方法和职责
测试类型
在项目中可能会应用多种测试类型。本大纲主要涉及下列四种测试类型:
功能测试是用于评估组件或系统应该执行的功能的测试。功能是测试对象应该做的事情。功能测试的主要目的是检查功能完整性、功能正确性和功能适合性。
非功能测试是用于评估组件或系统除功能特性之外的其他属性。非功能测试是测试“系统表现得多 好”。非功能测试的主要目的是检查软件的非功能质量特性。在 ISO/IEC 25010 标准中列出了不同类型 的非功能质量特性:
- 性能效率
- 兼容性
- 易用性
- 可靠性
- 信息安全性
- 维护性
- 可移植性
在开发生存周期的初期进行非功能测试有时是适当的(如,作为评审、组件测试或系统测试的一部 分)。很多非功能测试是从功能测试派生而出的,他们使用同样的功能测试,在执行功能时测试非功能 约束是否被满足,例如,通过检查执行完成某个功能所需要的时间,或者通过检查功能是否可以被移植 到新平台上。如果较晚发现非功能缺陷,将严重威胁到项目的成功。非功能测试有时需要在特定的测试 环境中进行,例如,执行易用性测试可能需要易用性测试实验室。
黑盒测试(参阅第 4.2 章节),是基于规格说明并根据测试对象外部的文档生成测试的测试技术。 黑盒测试的主要目的是检查系统行为是否与规格说明描述一致。
白盒测试(参阅第 4.3 章节),是基于结构并根据系统的实施或系统的内部结构(如代码、结构、 工作流和数据流)生成测试的测试技术。白盒测试的主要目标是通过测试将底层结构覆盖到可接受的水 平。
上述四种测试类型都可应用到所有的测试级别,尽管每个测试级别的重点有所不同。可使用不同的 测试技术为所有上述所提的测试类型导出测试条件和测试用例。
确认测试和回归测试
变更,通常指对组件和系统做出的改进,这种改进可以是增加新特征,或通过修改代码以移除缺陷进行修复。测试还应该包括确认测试和回归测试。
确认测试用于确认原有缺陷是否已经被成功修复的测试。根据风险的不同,测试人员可以对软件的缺陷修复版本进行不同的测试,包括:
- 执行先前由于存在缺陷而失败了的所有测试用例。
- 增加新的测试,以覆盖由于修复缺陷引发的任何变更。
但是,当进行缺陷修复工作的时间和预算有限时,确认测试的范围可能被严格限定,即仅执行重现原有(由缺陷引起的)失效的步骤,以检查失效是否已经消失。
回归测试确认变更未造成任何不良后果,包括已经经过确认测试的修复。这些不良后果可能会影响 进行更改的同一组件、同一系统中的其他组件,甚至其他关联的系统。回归测试可能不局限于测试对象本身,还可以与环境相关。建议首先执行影响分析以优化回归测试的范围。影响分析显示软件的哪些部分可能受到影响。
回归测试套件会被多次运行,通常回归测试用例的数量会随着每次迭代或发布而有所增加,因此可 以优先考虑自动化回归测试。这些测试的自动化应该在项目的早期开始。在使用持续集成(CI)时,比 如 DevOps(参阅第 2.1.4 节),最好也包括自动化回归测试。根据情况,可能包括不同级别的回归测试。
如果缺陷修复和/或变更发生在某些测试级别上,对测试对象进行的确认测试和/或回归测试就需要 在所有涉及的测试级别上进行。
维护测试
有多种不同类别的维护,可以是修正错误、应对环境变更、改进性能或改善维护性(详见 ISO/IEC 14764),因此,维护可以包括计划内的发布/部署和计划外的发布/部署(热修复 hot fix)。可以在 变更实施之前进行影响分析,基于系统在其他领域潜在后果的分析,帮助决定是否应该实施变更。在生 产环境中测试系统的变更,既包括评估更改实施的成功与否,也包括检查系统中保持不变的部分(通常 是系统的大部分)是否存在可能的回归错误。
维护测试范围通常依赖于:
- 变更引起的风险程度
- 现有系统的规模
- 变更的大小
维护以及维护测试的触发因素可以有以下几类:
- 修改,如计划中的改进(如,基于发布版本),修正错误产生的变更,或者热修复。
- 运行环境的升级或者迁移,如从一个平台迁移至另一个平台,可能需要进行与新运行环境有关的测试,也可能需要进行与软件变更有关的测试;或者当数据从一个应用迁移至处于维护状态 的另一个系统时,需要对数据迁移进行的测试。
- 退役,例如应用程序的生存周期即将结束。当系统退役时,如果需要长时间的数据保留,可能 需要测试数据归档。如果在归档期间需要某些数据,则可能还需要测试归档后的数据恢复和检索过程。
欢迎关注我的博客,如有疑问或建议,请随时留言讨论。