回归测试的四个步骤
扫描二维码
随时随地手机看文章
本文提供了一种创建和更新回归测试套件的结构化方法。回归测试套件中应该包含哪些类型的测试?应该运行哪些回归测试,如何应对失败的回归测试,回归测试套件如何发展?这些问题和其他考虑因素将逐步探讨。我将首先探讨回归测试的基本动态和考虑因素。然后,我将提供一组有助于通过回归测试实现长期软件稳定性的步骤。
回归测试的具体细节
假设我们对软件代码做了一些更改,任何类型的更改。我们如何确信这些更改不会对我们的代码整体产生负面影响?获得信心的一种方法是进行彻底的回归测试。编写和执行测试来检查和探索我们的代码在更改后的行为。因此,我们编写和执行的测试越多,我们就越有信心。是的,但也需要考虑实际成本——编写、执行和维护回归测试套件所需的时间、精力和金钱。
将所有可能的测试都包括进去会导致回归测试套件过于庞大而难以管理 — 而且,由于软件经常发生更改,因此运行起来非常困难。如果回归测试不能及时完成,开发过程就会中断。投入资金来解决这个问题是值得的,例如增加计算资源和/或雇用新员工来执行测试。然而,在某些时候,增加测试的附加价值可能不值得花费执行测试所需的额外资源。
另一方面,太小的测试套件无法充分覆盖软件的功能,并且会将太多的错误传递给用户。
向回归测试套件添加少量测试通常很简单。即使每个额外测试的边际成本很小,但累积起来,测试套件也会变得难以处理。从回归测试套件中删除测试可能会产生问题。如果客户报告了被删除的测试之一会发现的错误,该怎么办?
测试用例选择技术
选择正确的测试用例涉及识别直接和间接受影响的测试用例。我们至少应该知道客户最常使用哪些功能,哪些测试涵盖重要功能以及哪些测试经常失败。其他选择技术包括线性方程、符号执行、路径分析、数据流分析、程序依赖图、系统依赖图、修改分析、集群识别、切片、图形遍历和修改后的实体分析。在选择选择技术时,考虑以下标准很有用:
包容性
包容性是指回归测试选择技术在多大程度上包含了可能暴露软件最近更改所引入的故障的测试。如果一种技术能够有效地识别和选择涵盖代码修改或受影响部分的测试,则该技术被认为更具包容性。包容性对于确保所选测试全面覆盖自上一个测试周期以来所做的更改至关重要。不安全的技术的包容性低于 100%。
精确
精确度衡量回归测试选择技术排除当前测试目标不需要的测试的能力。精确技术应尽量减少包含对检测与最近修改相关的故障没有帮助的测试。此标准旨在防止过度测试,因为过度测试可能导致测试执行时间延长和资源效率低下。
效率
效率评估使用特定技术执行回归测试所需的计算和时间资源。高效的技术应该能够快速识别和选择相关的测试子集,同时最大限度地缩短总体测试时间。这对于具有大量测试套件的大型软件系统尤其重要,因为需要更快的测试周期来支持敏捷开发实践。
概论
通用性评估回归测试选择技术在各种软件测试场景和领域的适用性。更通用的技术可以在广泛的实际情况中使用,而无需进行大量定制。它不应该针对特定类型的软件或测试环境过度专业化,使其能够适应不同的开发项目。
接下来,我们将探讨回归测试的四个步骤。我们首先确定被测修改后的代码。确定需要执行的测试,然后是平衡测试套件大小的步骤。这一切都与我们的测试执行结果有关。我们测试的范围有多广,我们的测试运行得有多快,我们对测试结果提供被测系统的真实情况有多大信心?随着我们在四个步骤中的每一步都做得越来越好,软件的长期稳定性就可以随之而来。
步骤 1:识别修改的代码
确定自上一次回归测试周期以来软件中被修改的具体部分。这可以通过版本控制系统和变更跟踪机制来实现。此步骤是后续回归测试步骤的基础。
版本控制和变更跟踪
为了识别修改的代码,我们可以使用版本控制系统和变更跟踪机制。Git、SVN 或 Mercurial 等版本控制系统会保留对软件源代码所做更改的历史记录。开发人员使用这些系统提交更改以及描述性提交消息。变更跟踪机制还可以包括问题跟踪系统,例如 JIRA 或错误数据库。
分析提交历史
在版本控制系统中,我们可以检查提交历史记录以查看代码库中发生了哪些更改。每次提交通常都包含有关修改了哪些文件、添加、删除或修改了哪些代码行以及对所做更改的描述的信息。通过分析此提交历史记录,我们可以精确定位已更改的具体代码。
识别已修改的文件和代码部分
根据提交历史,我们可以识别修改过的文件以及这些文件中发生更改的代码部分。这可能包括函数、类、方法,甚至是个别代码行。在识别修改过的代码时,尽可能细致是至关重要的。
文档变更
记录变更的性质很有帮助。这些是修改、错误修复、新功能、增强功能还是其他类型的变更?了解变更的性质可以指导我们的回归测试策略。
与开发团队的合作
在此步骤中,测试团队和开发团队之间的协作至关重要。测试人员应与开发人员沟通,以清楚了解变更及其对软件功能的影响。
可追溯性
在已识别的修改代码与相应的需求或用户故事之间建立可追溯性。这有助于确保修改与预期功能一致,并且我们的回归测试充分涵盖了这些更改。
在第 1 步结束时,我们应该有一个完整的代码修改列表,以及有关更改的详细信息。此信息可作为第 2 步中选择相关测试的基础,确保我们将回归测试工作重点放在最有可能受到最近修改影响的软件领域。这种有针对性的方法是我们回归测试结构的支柱。它对于高效和有效的回归测试至关重要。
第 2 步:选择相关测试
一旦我们确定了修改后的代码,下一步就是选择相关测试以纳入我们的回归测试套件。这一步对于确保我们彻底测试对软件所做的更改至关重要。
覆盖标准
此步骤的第一部分涉及评估覆盖率标准,以确定哪些类型的测试应包含在我们的回归测试套件中。覆盖率标准帮助我们定义测试工作的范围。两个常见的覆盖率标准是:
节点覆盖率(或方法调用覆盖率)
节点覆盖侧重于识别修改后的代码中从未调用的方法或函数。此标准对于确保代码库的所有部分都得到执行至关重要,这有助于发现死代码或未使用的功能。
结构覆盖
结构覆盖更进一步,分析哪些代码路径受到修改的影响。此标准考虑是否调用了方法以及这些方法内的具体执行路径。语句覆盖、分支覆盖和路径覆盖等技术属于此类别。它有助于确保调用每个方法,并测试不同的执行分支和场景。
测试选择
对于步骤 1 中确定的每个修改,我们需要选择直接或间接执行修改后代码的测试。
直接受影响的测试
确定直接覆盖修改后代码的测试。这些测试专门针对已更改的函数或方法。运行这些测试有助于确保修改按预期运行并且没有引入新的错误。
间接影响的测试
某些更改可能会对软件的其他部分产生连锁反应。间接影响的测试可能不直接执行修改后的代码,但会以某种方式与其交互。例如,如果一个模块的更改影响另一个模块的输出,则还应考虑对后者模块的测试。
测试充分性
评估我们所选测试的充分性至关重要。问问自己这些测试是否对修改后的代码提供了足够的覆盖范围。考虑更改的复杂性和对软件行为的潜在影响。在某些情况下,我们可能需要创建专门针对更改的新测试。
文档
保存每次修改所选择的测试的完整文档。此文档可确保透明度,并可轻松跟踪不同代码更改的测试覆盖率。
在第 2 步结束时,我们应该有一个定义良好的回归测试套件,其中包含有效验证修改后的代码所需的测试。这种有针对性的测试选择方法可确保我们的测试工作全面,帮助我们在开发周期的早期发现回归和缺陷。
步骤 3:平衡测试套件大小
虽然选择能够充分覆盖修改后的代码的测试至关重要,但同样重要的是避免在回归测试套件中包含所有可能的测试。管理庞大的测试套件可能会耗费大量时间和资源。回归测试的第三步可以专注于有效管理回归测试套件的大小。在全面测试和实用性之间取得平衡至关重要。
避免包括所有可能的测试
在我们的回归测试套件中包含所有可以想到的测试通常是不可行的。随着软件的发展,测试数量会呈指数级增长,因此在合理的时间范围内执行所有测试是不切实际的。运行一组详尽的测试可能会大大减慢测试过程,从而难以跟上开发速度。应该确定回归测试套件的最佳大小。该大小可以基于资源可用性、时间限制、风险、开发过程和优先级等因素。
可用资源
考虑可用于测试的硬件、软件和团队成员。有限的资源可能会限制我们的测试套件的大小。
时间限制
注意项目截止日期和发布时间表。我们应该力争在可用时间内完成回归测试,同时确保足够的覆盖范围。
风险评估
评估修改代码的重要性和缺陷的潜在影响。高度关键的代码更改可能需要更广泛的测试,而不太重要的更改可以用较小的测试套件进行覆盖。
开发流程注意事项
测试套件大小的选择应该与开发过程保持一致。
在敏捷方法中,变化频繁,回归测试通常执行得更频繁(例如,在每个冲刺或迭代之后)。因此,每个回归周期的测试套件大小可能较小,以保持测试敏捷并对变化做出响应。
在更传统的开发过程中,变更频率较低,发布频率也较低,因此回归测试的执行频率也较低。在这种情况下,我们可能会有更大的测试套件,涵盖更广泛的功能。
优先级
考虑根据关键业务功能、常用功能或存在缺陷历史的区域等因素对测试进行优先排序。即使测试套件大小有限,这也有助于确保软件中最关键的部分得到彻底测试。
文档
我们关于测试套件大小的决定应该记录下来。该文档将作为我们测试策略的指南,并为所有利益相关者提供透明度。
平衡回归测试套件的大小对于高效测试至关重要。它使我们能够将测试工作重点放在最重要的地方,同时确保我们能够在项目限制内完成回归测试。通过根据具体情况调整测试套件的大小,我们可以在回归测试的彻底性和实用性之间取得适当的平衡。
步骤 4:执行测试并处理结果
有了平衡的回归测试套件,我们现在可以执行它并评估我们的测试结果。
失败的测试
如果一个或多个回归测试失败,请调查失败是由于软件修改中的错误还是回归测试本身的问题。测试失败的原因是正确的还是错误的原因?测试失败的正确原因是发现了错误。错误原因是没有错误,测试失败是因为编写或执行方式不当。无论哪种情况都需要额外的工作。
通过的测试
如果没有回归测试失败,那么我们应该能够自信地回答以下问题。我们的测试通过是出于正确的原因还是错误的原因?发生这种情况的一个正确原因是测试执行了代码中正常运行的部分。但是,测试可能会通过测试,因为它实际上可能什么都没测试。这是一个没有得到适当维护的旧测试,它目前没有测试它打算测试的内容。它碰巧意外地通过了测试。
测试自动化
回归测试是测试自动化带来最大好处的领域。理想情况下,我们希望确保所有回归测试都是自动化的。如果这始终可行且实用,那么回归测试的执行将不需要人工干预,并且可以随时重复。不幸的是,有些自动化回归测试可能会因未知原因而失败,而有些则经常失败,有些则不定期失败。有些测试执行得很快,有些则很慢,有些测试可能在某些运行中执行得很快,而在其他运行中执行得很慢。这些问题可能会得到解决,但如果我们不解决它们,随着回归测试数量的增加,它们只会变得更糟。
测试自动化在持续集成/持续交付 (CI/CD) 流程中使用时最有价值。如果我们的项目遵循 CI/CD 流程,我们可能有机会自动化和简化回归测试。作为 CI/CD 流程的一部分,可以更频繁地运行较小、有针对性的测试套件,从而在开发周期的早期发现回归问题。
请记住,自动化测试与手动测试的目标相同:让我们清楚地了解被测系统如何按预期运行。我们应该对手动测试结果充满信心,也应该对自动化测试结果充满信心。当自动回归测试套件完成执行时,我们应该确信测试结果描绘了被测系统的真实情况。我们越有信心,我们花在调试自动化测试结果和识别真正的错误或修复无用测试上的时间就越少。
包起来
为了适应软件变化,我们必须首先认识到,适用于一个软件版本的回归测试套件可能不足以满足后续版本的需要。第一步是确定代码中发生了哪些变化。我们必须考虑不同类型的代码变化,例如创建新功能、改进现有功能、修复错误和故障、重构和性能改进。即使功能保持不变,我们也必须重新评估回归测试套件的适用性,尤其是在代码重组的情况下。
第二步是确定要将哪些测试纳入我们的回归测试套件。我们可以选择涵盖步骤 1 中确定的代码更改的所有相关测试。应根据需要创建或修改回归测试套件,以纳入涵盖更改的功能或代码路径的新测试。请记住,没有完美的指标。例如,节点覆盖率可能是一个有用的指标,但即使节点覆盖率很高,测试套件中也可能存在差距。例如,测试套件可能涵盖程序中的所有节点,但可能不会测试重要的输入值或执行路径。
第三步是平衡测试套件的大小。这一点非常重要,因为测试数量增加和/或测试执行完成所需的时间成为障碍。由于软件更改而不再相关的过时测试可以被删除。
测试执行完成后,仔细检查测试结果非常重要。一旦我们确信测试结果值得信赖,我们就可以与适当的利益相关者分享我们的发现。