关键词:覆盖(coverage),调试(debugging),缺陷(defect),错误(error),失效(failure),质量 (quality),质量保证(quality assurance),根本原因(root cause),测试分析(test analysis),测试依据(test basis),测试用例(test case),测试完成(test completion),测 试条件(test condition),测试控制(test control),测试数据(test data),测试设计(test design),测试执行(test execution),测试实施( test implementation),测试监测(test monitoring),测试对象(test object),测试目的 test objective),测试规划(test planning),测试规程(test procedure),测试结果(test result),测试(testing),测试件 (testware),可追溯性(traceability),确认(validation),验证(verification)。
什么是软件测试
软件系统是我们日常生活中不可或缺的一部分。大多数人都曾遇到过软件无法按预期运行的经历。 无法正常工作的软件可能会导致许多问题,包括金钱、时间或商业声誉的损失;在极端情况下甚至会造 成人员伤亡。软件测试评估软件质量,有助于降低软件运行失败的风险。
软件测试是一系列发现缺陷和评估软件产品质量的活动。这些软件产品在被测试时称为测试对象。 关于测试的常见误解是认为软件测试仅包含执行测试(即运行软件并检查测试结果)。其实,软件测试还包括其他活动,并且必须与软件开发生存周期保持一致(参阅第 2 章)。
关于测试的另一个常见误解,认为测试完全专注于验证测试对象。虽然测试涉及验证,即检查系统 是否满足指定要求,但它还涉及确认,即检查系统在其操作环境中是否满足用户和其他利益相关方的要 求。
测试可以是动态的或静态的。动态测试涉及软件的执行,而静态测试不涉及软件的执行。静态测试 包括评审(参阅第 3 章)和静态分析。动态测试使用不同类型的测试技术和测试方法来生成测试用例 (参阅第 4 章)。
测试不仅仅是技术活动。它还需要进行适当的计划、管理、估算、监测和控制(参阅第 5 章)。
测试人员使用工具(参阅第 6 章),但重要的是要记住,测试很大程度上是智力活动,要求测试 人员具备专业知识、使用分析技能并运用批判性思维和系统思维(Myers,2011 年;Roman,2018 年)。
ISO/IEC/IEEE 29119-1(GB/T 38634.1-2020)标准提供了有关软件测试概念的更多信息。
测试目的
典型的测试目的为:
- 评估工作产品,例如需求、用户故事、设计和代码。
- 触发失效并发现缺陷。
- 确保所需的被测对象的覆盖率。
- 降低软件质量不足的风险级别。验证是否已满足指定需求。
- 验证测试对象是否符合合同、法律和监管要求。
- 向利益相关方提供信息,使他们能够做出明智的决策。
- 建立对被测对象质量的信心。
- 确认被测对象是否完整并按利益相关方的预期工作。
根据不同的情况,测试的目的可能会有所不同;其中包括被测试的工作产品、测试级别、风险、遵循的软件开发生存周期(SDLC)以及与业务环境相关的因素,例如公司结构、竞争考虑因素,或上市时间。
测试与调试
测试和调试是不同的活动。测试可以触发由软件缺陷引发的失效(通过动态测试),也可以直接发现测试对象中的缺陷(通过静态测试)。
当动态测试(参阅第 4 章)触发失效时,调试涉及查找失效原因(缺陷)、分析并消除这些原因。这种情况下,典型调试过程包括:
- 重现失效。
- 诊断(找到根本原因)。
- 修复失效的原因。
随后的确认测试将检查修复是否解决了问题。确认测试最好是由执行初始测试的同一个人来完成。 还可以执行后续的回归测试,以检查修复是否导致测试对象的其他部分出现失效(有关确认测试和回归测试的更多信息,请参阅第 2.2.3 节)。
静态测试是为了发现缺陷,而调试则是为了消除缺陷。因为静态测试是直接发现缺陷,并且不会导致失效,所以不需要重现或诊断(参阅第 3 章)。
为什么需要测试
测试作为一种质量控制形式,有助于在设定的范围、时间、质量和预算限制内实现商定的目标。测试对成功的贡献不应仅限于测试团队的活动。任何利益相关方都可以利用他们的测试技能使项目更接近成功。测试组件、系统和相关文档有助于识别软件中的缺陷。
测试对成功的贡献
测试提供了经济高效的发现缺陷的方法。这些缺陷可以通过后续活动进行消除(通过调试——一种非测试活动),因此测试间接地提高测试对象的质量。
测试提供了在软件开发生存周期(SDLC)的各个阶段直接评估测试对象质量的方法。这些措施是大型项目管理活动的一部分,有助于做出进入软件开发生存周期(SDLC)下一阶段的决策,例如决定版本是否发布。
测试为用户提供了开发项目的间接代表,测试人员确保他们对用户需求的理解贯穿于整个开发生存周期。另一种方法是让用户代表参与开发项目,但由于成本高且缺乏合适的用户,通常是不好操作。
为了满足合同或法律要求,或遵守监管标准,也可能需要进行测试。
测试和质量保证(QA)
虽然人们经常混用术语“测试”和“质量保证”(QA),但测试和 QA 并不相同。测试是质量控制 (QC) 的一种形式。
质量控制(QC)是以产品为导向的纠正方法,侧重于支持实现适当质量级别的活动。测试是质量控制的主要形式,而其他方法包括形式化方法(模型检查和正确性证明)、模拟和原型设计。
质量保证(QA)是以过程为导向的预防性方法,侧重于过程的实施和改进。它的工作原理是,如果正确遵循良好的过程,就会产生良好的产品。质量保证(QA)适用于开发和测试过程,是项目中每个人 的责任。
测试结果会被质量保证(QA)和质量控制(QC)使用。在质量控制(QC)中,测试结果用于修复缺陷,而在质量保证(QA)中,测试结果提供关于开发和测试过程执行情况的反馈。
错误、缺陷、失效和根本原因
人会犯错误(error、mistake),从而产生缺陷(defect、fault,bug),进而导致失效 (failure)。人犯错的原因多种多样,例如时间压力、工作产品的复杂性、过程、基础设施或交互, 或者仅仅是因为疲劳或缺乏足够的培训。
缺陷可以在文档(如需求规格说明或测试脚本)中找到、在源代码中或者在支持工件中(例如构建 文件)找到。软件开发生存周期(SDLC)早期生成的工件中的缺陷,如果未被发现,通常会导致生存周 期后期产生带有缺陷的工件。如果代码中的缺陷被执行,系统可能无法按照应有的方式执行,或者执行 了不应该执行的操作,从而导致失效。某些缺陷在执行时总是会导致失效,而另一些缺陷只会在特定情况下导致失效,有些缺陷可能永远不会导致失效。
错误和缺陷并不是导致失效的唯一原因。失效也可能是由环境因素引起的,例如辐射或电磁场引起 固件中的缺陷。
根本原因是问题发生的根本原因(例如,导致错误的情况)。通过根本原因分析来识别根本原因, 通常在发生失效或识别出缺陷时进行根本原因分析。一般认为,通过解决根本原因,例如消除根本原 因,可以防止类似失效或缺陷,或降低其出现的频率。】、
测试原则
多年来,人们已经提出了许多测试原则,提供了适用于所有测试的通用指南。本教学大纲描述了七个测试原则。
- 测试显示了缺陷的存在,而不能说明缺陷不存在。测试可以表明测试对象中存在缺陷,但不能证明没有缺陷(Buxton 1970)。测试降低了测试对象中未发现缺陷的可能性,但即使没有发现缺陷,测试也无法证明测试对象的正确性。
- 穷尽测试是不可能的。除非在小型的案例中,否则测试所有的情况是不可行的(Manna,1978 年)。与其试图进行穷尽测试,不如使用测试技术(参阅第 4 章)、测试用例优先级(参阅第 5.1.5 节)和基于风险的测试(参阅第 5.2 节)来聚焦测试工作。
- 早期测试可以节省时间和费用。在软件开发过程的早期移除的缺陷不会在后续的衍生工作产品中 产生更多缺陷。由于在软件开发生存周期(SDLC)后期发生的故障较少,因此,可以降低质量成本 (Boehm,1981 年)。为了早期发现缺陷,应尽早开始静态测试(参阅第 3 章)和动态测试(参阅第 4 章)。
- 缺陷的集群效应。通常大多数已发现的缺陷出现在少数系统组件中,或者少数系统组件是引起大多数操作失效的原因(Enders,1975 年)。这一现象是帕累托原理的一个例证。预测的缺陷集群和在测 试或运行过程中观察到的实际缺陷集群是基于风险的测试的重要输入(参阅第 5.2 节)。
- 测试会无效。如果重复多次相同的测试,在检测新缺陷方面会变得越来越无效(Beizer,1990 年)。为了克服这种影响,可能需要修改现有的测试和测试数据,并且可能需要编写新的测试。然而,在某些情况下,重复相同的测试可能会产生有益的结果,例如,在自动化回归测试中(参阅第 2.2.3 节)。
- 测试活动依赖于测试周境。没有一种放之四海而皆准的测试方法。周境不同,测试的方式也不同 (Kaner,2011 年)。
- 不存在缺陷的谬论。期望软件验证会确保系统的成功是一种谬论(即误解)。彻底测试所有指定 的需求并修复发现的所有缺陷,仍然可能产生不能满足用户需求和期望的系统,不能帮助实现客户的业 务目标,并且与其他竞争系统相比处于劣势。除验证外,还应进行确认(Boehm,1981 年)。
测试活动、测试件和测试角色
测试依赖于周境,但在高级别上,会有一些共同的测试活动集,如果没有这些活动,测试目标将很难达成。这些测试活动集形成测试过程。测试过程可根据特定场景进行裁剪。哪些测试活动应包含在测 试过程中,如何实施,何时开始,通常会依据具体情况,体现在测试规划中(见第 5.1 节)。
以下各节将从测试活动、任务、周境的影响、测试件、测试件与测试依据之间的双向可追溯性和测 试角色等方面对测试过程进行一般性描述。
有关测试过程的更多信息可参阅 ISO/IEC/IEEE 29119-2(或 GB/T 38634.2-2020)标准。
测试活动和任务
测试过程通常由以下主要活动组成。尽管这些活动看似遵循逻辑顺序,但通常采用迭代或者并行方式实施。这些测试活动通常需要针对系统和项目进行裁剪。
测试规划包括定义测试目的,在整体环境的约束下选择可达到目的的最佳方法。测试规划将在第 5.1 节中进一步说明。
测试监测和控制。测试监测包括持续检查所有测试活动,并且将实际进度与计划进行比较。测试控制包括采取必要的行动来实现测试目的。第 5.3 节对测试监测和控制进一步说明。
测试分析包括分析测试依据以识别可测试的特征,定义相关测试条件的优先级,以及有关的风险和风险级别(参阅第 5.2 节)。对测试依据和测试对象进行评估,以识别它们可能包含的缺陷并评估其可测试性。测试分析通常由掌握测试技术的人员提供支持(参阅第 4 章)。测试分析根据可度量的覆盖准则回答“测试什么?”的问题。
测试设计包含如何将测试条件转化成测试用例和其他测试件(例如,测试章程)。这项活动通常与识别覆盖项有关,可以作为具体选择哪些测试用例输入的指南。测试技术(参阅第 4 章)可用于支持此活动。测试设计还包括定义测试数据需求、设计测试环境以及确认所需的基础设施和工具。测试设计回 答“如何测试?”的问题。
测试实施包括创建或获取测试执行所需的测试件(例如,测试数据)。测试用例可以被组织到测试 规程中,并且经常被组装成测试套件使用。创建人工和自动化的测试脚本。为实现高效的测试执行,测 试规程要按照优先级在测试执行进度表中排序。构建测试环境,并验证其设置的正确性。
测试执行包括根据测试执行进度表执行测试(测试运行)。测试执行既可以人工进行也可以自动进行。测试执行可以采取多种形式,包括持续测试或结对测试会话。将测试的实际结果与预期结果进行比较。记录测试结果。分析导致异常发生的可能原因。该分析以观察到的失效为依据报告异常(参阅 5.5 节)。
测试完成活动通常发生在项目里程碑处(例如,发布、迭代结束、测试级别完成),针对任何未解决的缺陷、变更请求或产品待办事项列表。未来可能有用的测试件都会被识别并归档,或移交给适当的团队。测试环境被恢复到约定状态。对测试活动进行分析,以确定未来迭代、发布或项目的经验教训和 改进(见 2.1.6 节)。创建测试完成报告并与利益相关方沟通。
周境中的测试过程
测试不是孤立进行的。测试活动是组织内执行的开发过程的组成部分。测试由利益相关方资助,其最终目标是协助利益相关方达成其业务需要。因此,测试的执行方式将取决于多种环境因素,包括:
- 利益相关方(需要、期望、需求、合作意愿等)。
- 团队成员(技能、知识、经验水平、工作效率、培训要求等)。
- 业务领域(测试对象的重要性、已识别的风险、市场要求、特定的法律法规等)。
- 技术因素(软件类型、产品架构、使用的技术等)。
- 项目约束(范围、时间、预算、资源等)。
- 组织因素(组织架构、现有政策、已在应用的实践等)。
- 软件开发生存周期(工程实践、开发方法等)。
- 工具(可用性、易用性、依从性等)。
这些因素将对测试相关的各种问题产生影响,包括:测试策略、使用的测试技术、测试自动化程 度、需要的覆盖级别、测试文档的详细程度、报告等。
测试件
测试件是根据第 1.4.1 节中描述的测试活动所创建的输出工作产品。不同组织在生成、结构、命 名、组织和管理工作产品方面存在显著差异。适当的配置管理(参阅第 5.4 节)可确保工作产品的一致 性和完整性。以下是工作产品列表的部分内容:
- 测试规划工作产品包括:测试计划、测试进度表、风险记录表以及入口和出口准则(参阅第 5.1 节)。风险记录表是包含风险、风险可能性、风险影响以及风险缓解信息的列表(参阅第 5.2 节)。测试进度表、风险记录表、入口和出口准则通常是测试计划的一部分。
- 测试监测和控制工作产品包括:测试过程报告(参阅第 5.3.2 节)、文档化的控制指令(参阅 第 5.3 节)和风险信息(参阅第 5.2 节)。
- 测试分析工作产品包括:(按优先级排序)测试条件(例如,验收准则,参阅第 4.5.2 节), 在测试依据中发现的有关缺陷的缺陷报告(如果该缺陷还没有被直接修复)。
- 测试设计工作产品包括:(按优先级排序)测试用例、测试章程、覆盖项、测试数据需求和测试环境需求。
- 测试实施工作产品包括:测试规程、自动化测试脚本、测试套件、测试数据、测试执行计划和 测试环境要素。测试环境要素的实例包括:桩、驱动器、模拟器和服务虚拟化。
- 测试执行工作产品包括:测试日志和缺陷报告(参阅第 5.5 节)。
- 测试完成工作产品包括:测试完成报告(参阅第 5.3.2 节)、后续项目或迭代的改进行动项、 文档化的经验教训和变更请求(例如,产品待办事项)。
测试依据和测试件之间的可追溯性
为了实施有效的测试监测和控制,测试过程中建立和维护测试依据元素、与元素相关的测试件(例如测试条件、风险、测试用例)、测试结果和发现的缺陷之间的可追溯性非常重要。
准确的可追溯性可支持覆盖评估,测试依据中定义可衡量的覆盖准则非常有用。覆盖准则可以作为关键绩效指标,推动活动的进行,以展示测试目的达成的程度(参阅第 1.1.1 节)。例如:
- 测试用例对需求的可追溯性可以验证测试用例是否覆盖了需求。
- 测试结果对风险的可追溯性可用于评估测试对象中剩余风险的级别。
除了评估覆盖范围之外,良好的可追溯性还可以确定变更的影响、促进测试审计,并有助于满足 IT 治理准则。良好的可追溯性还可以通过包含测试依据元素的状态,使得测试进度报告和测试完成报告更 易于理解。也有助于以可理解的方式向利益相关方传达测试技术方面的问题。可追溯性提供了针对业务 目标评估产品质量、过程能力和项目进展的信息。
测试活动中的角色
在本大纲中,涵盖了测试活动中的两个主要角色:测试管理角色和测试角色。这两个角色所承担的活动和任务取决于项目和产品的周境、人员的技能以及组织等因素。
测试管理角色全面负责测试过程、测试团队以及测试活动的领导工作。测试管理角色主要关注测试规划、测试监测和控制以及测试完成活动。测试管理角色开展工作的方式因周境而异。例如,在敏捷软件开发中,一些测试管理任务可由敏捷团队处理。对于跨多个团队或整个组织的任务可由开发团队之外的测试经理执行。
测试角色对测试的工程(技术)方面负有整体责任。测试角色主要关注测试分析、测试设计、测试实施和测试执行等活动。
不同的人员可能在不同的时间点扮演这些角色。例如,测试管理角色可以由团队领导、测试经理、 开发经理等担任。也可以一个人同时承担测试和测试管理的角色。
测试中的基本技能和良好实践
技能是指个人根据自身的知识、实践和才能做好某件事的能力。好的测试人员应该具备一些基本技能才能把他们的工作做好。好的测试人员应该是有效的团队合作者,并且能够在不同测试独立性级别上开展测试工作。
测试所需的通用技能
以下虽然是些通用的技能,但它们对测试人员来说尤其有意义:
- 测试知识(例如,通过使用测试技术提高测试的有效性)。
- 全面、细致、好奇心、注重细节、有条不紊(对识别缺陷,尤其对于发现难以发现的缺陷)。
- 良好的沟通技巧、积极的倾听、具有团队合作精神(与所有利益相关方有效互动,以可理解的 方式向他人传递信息,并报告和讨论缺陷)。
- 分析性思维、批判性思维、创造力(用以提高测试的有效性)。
- 技术知识(提高测试效率,例如使用适当的测试工具)。
- 领域知识(能够理解并与最终用户/业务代表沟通)。
测试人员经常是坏消息的传递者。责怪坏消息的传递者是常见的人类特质。因此,沟通技巧对于测 试人员来说至关重要。传达测试结果可能被视为对产品及其作者的批评。确认偏见(Confirmation bias)可能会使人们难以接受与当前信念不符的信息。尽管测试对项目的成功和产品质量有很大贡献, 但有些人可能会将测试视为破坏性的活动。为了改善这种观点,应以建设性的方式沟通有关缺陷和失效 的信息。
完整团队方法
能够在团队环境中有效地工作并积极为团队目标做出贡献,是测试人员重要的技能。完整团队方法 (来自”极限编程”(参阅第 2.1 节)的实践)基于这项技能构建。
在完整团队方法中,所有团队成员都具有进行各种类型任务的知识和能力,并且每个人都要对质量负责。团队成员共享相同的工作空间(物理或虚拟),共址工作有助于沟通和互动。完整团队方法可提升团队活力,增强团队内部的沟通和协作,并通过充分利用团队内不同的技能,产生协同效应,从而使项目获益。
为确保达到期望的质量水平,测试人员要与团队其他成员密切合作。这些合作包括:与业务代表协 作,帮助他们创建适合的验收测试;与开发人员协作,达成测试策略和测试自动化方法的共识。测试人 员能够向团队其他成员传授测试知识,从而影响产品的开发。
由于对周境的依赖,完整团队方法可能并不总是适用。例如,在某些状况下,如安全关键系统,可 能需要更高水平的测试独立性。
测试独立性
因为作者和测试人员之间存在认知偏差(cognitive biases)(参阅 Salman,1995),因此一定程度的独立性可以使测试人员更有效地发现缺陷。然而,独立性并不能取代熟悉性,例如,开发人员可以 高效地发现自己代码中的许多缺陷。
工作产品可以交由作者进行测试(无独立性),或交由来自作者同一团队的同行进行测试(一定的独立性),或交由组织内非作者团队的测试人员进行测试(高独立性),或交由组织外部的测试人员进 行测试(非常高的独立性)。对于大多数项目而言,通常最好使用多个独立性级别的测试。例如,开发人员进行组件测试和组件集成测试,测试团队进行系统测试和系统集成测试,业务代表进行验收测试。
测试独立性的主要优势在于,独立的测试人员与开发人员相比,由于背景、技术视角、以及认知偏向的差异,更可能识别出不同类型的失效和缺陷。此外,独立的测试人员可以验证、质疑或推翻利益相关方在系统规格说明和系统实施期间所做的假设。
尽管如此,测试独立性也存在一些缺点。独立的测试人员可能与开发团队脱离,可能导致缺乏协作、沟通出现问题或与开发团队形成对立关系。开发人员可能会丧失对质量的责任感。独立测试人员可能被视为瓶颈,或被指责为发布延迟负有责任。