11 项单元测试最佳实践

一个男人使用笔记本工作,有 2 台显示器协助。

作者

Phill Powell

Staff Writer

IBM Think

Ian Smalley

Staff Editor

IBM Think

什么是单元测试最佳实践?

单元测试最佳实践支持编写隔离式独立运行,并显示出一致的确定属性的单元测试。

良好的单元测试体现测试驱动开发 (TDD) 原则,并利用模拟对象与存根实现隔离。最佳实践还支持持续整合自动化测试。

什么是单元测试?

在各类测试中,单元测试能以近乎微观的视角检测代码单元,后者是通过软件测试进行评估的最小单个组件。有效单元测试的关键要素是隔离,以确保准确评估单元功能。

单元测试的优点包括通过自动化加快软件开发过程,并通过将调试嵌入到软件开发生命周期 (SDLC) 的早期来实现劳动成本节约。此类调试工作支持保留开发期间所做的任何代码更改,并全程提高代码质量。

单元测试框架可帮助测试人员在各个单元上运行测试并构建更强大的整体代码库。测试通过意味着:当测试验证特定代码片段时,测试执行正常且所有关联检查(又称“断言”)均已成功实现。测试通过表明单元运行符合预期。

什么是依赖项?

单元测试是一个多层面的话题,需要对各个方面进行描述。其中一个领域涉及依赖项。在单元测试的语境中,依赖项是指代码单元正常运行所需的外部服务或组件。

重要的是要有效管理此类依赖项,以编写可靠和可维护的单元测试(也就是说,在代码库的全面演变过程中,测试在长期环境中保持有效、灵活和有用)。

通过有效管理依赖项,测试人员可以构建更强大、更可靠的测试套件,确保其按照预期行为运行。开发人员使用依赖项注入将依赖项相关的代码行插入(或“注入”)代码库。

IBM DevOps

什么是 DevOps?

Andrea Crawford 阐述了什么是开发运维、开发运维的价值,以及开发运维实践和工具如何帮助您完成从应用程序构思到生产的整个软件交付管道。本课程由 IBM 资深思想领袖主导,旨在帮助企业领导者获得所需的知识,以优先考虑能够推动增长的 AI 投资。

单元测试的 11 个最佳实践

本文所述的各种策略都遵循最佳实践,且体现实操型测试方法。

1. 充分利用 mock 和 stub

测试环境依赖于使用 mock 和 stub 来促成测试所需的深度隔离。

mock 对象是有效的重复,通过将模拟对象置于深度隔离状态来帮助测试人员评估实际对象的可能行为。

存根可为分析师提供与外部依赖项(例如组件、文件系统和数据库)存在潜在交互行为的数据。

2. 研究极端使用模式

错误检测是单元测试的核心部分。测试人员对单元运行参数或边界附近出现的极端使用模式进行评估。这些情况被称为边缘情况,可能不易察觉,例如在越界数组访问中。在这里,测试人员会发现分项索引超出了该索引的最大允许值。

在这种情况下,测试人员通常会被迫重构代码,这意味着即使代码仍在运行,也要重构代码。

3. CI/CD 管道的使用

持续整合/持续交付 (CI/CD) 管道对测试过程至关重要,因为它们可以自动执行测试功能。

通过运行 CI/CD 管道,可以在代码更改时随时进行自动化单元测试。自动化测试能够在开发过程的早期检测到错误,并有助于保障代码质量。

4. 保持测试简短、简单且快速

许多因素影响测试的可维护性。要被视为可维护,测试代码必须表现出最佳的可读性、清晰度和健全的识别方法。简而言之,测试应具备高质量的生产代码。

它们还应该编写为处理特定模块的小型和有针对性的测试。创建测试时还应考虑速度,以便更快、更频繁地进行测试。

5. 注意命名规范

如果测试人员不遵守正确的命名约定,那么原本良好的测试就很容易被淹没。测试名称需要简洁,但包含足够的措辞来充分描述主题,以便可以根据需要找到和调用它们。将测试标记为“Test-1”根本无法提供有关测试内容或测试原因的充足详细信息。

6. 为所有可能发生的情况创建测试

建立强大的代码库,需要构思涵盖正面和负面场景的测试。对于正面场景,测试人员需要针对有效输入添加测试。对于负面场景,测试人员则需要预测意外或无效输入。

保持边缘情况和边界条件的测试覆盖率也很重要,这可以确保您的代码足够灵活,能够处理所有类型的情况。

7. 遵循 AAA 模式

测试应遵循标准测试模式,例如完善的 Arrange-Act-Assert (AAA) 模式。

AAA 模式要求在单元测试中整理和准备代码,然后执行测试所需的任何步骤。最后,它还涉及评估测试用例,以观察其能否生成预期的测试结果。

8. 充分测试,经常测试

有多少代码是可测试的?该数量将根据贵组织的具体情况而有所不同。但是,当测试是目标时,最好尽可能现实和可行地瞄准更高的目标。

测试人员应尝试将测试覆盖率保持在 70-80% 之间,并确保定期的测试频率。

9. 恢复测试环境

测试应在干净的测试环境中进行。这意味着测试人员应遵循与在测试结束后恢复系统相关的拆除程序。

典型的拆除操作可能需要测试人员删除临时文件、更改全局变量或关闭数据库连接。否则,很容易发生测试失败,因为现有的杂散代码位会阻碍未来的测试。

10. 切勿遗忘公共接口

规划单元测试时,请记住代码将具有的使用类型。公共接口也需要测试,代码中的任何公共属性或方法也需要测试。

为了保持专注,最好将测试实施限制在公共应用程序编程接口 (API) 的那些细节上。

11. 保持测试与代码功能相适应

测试专用代码的功能与该系统可能遵循的底层业务规则之间存在显著差异。正在执行的测试应单独评估代码功能。

单元测试工具

开发人员有各种工具可用于单元测试。以下是最常用的:

  • Jest:Jest 的框架可分析 React 和 JavaScript 组件,是熟练开发人员和新手(欣赏其易用性)的首选。它旨在提供零配置测试体验,设置时间极短并可快速创建测试。另一个优点是 Jest 报告测试覆盖率并评估需要验证的代码总量的方式。
  • JUnit:Java 组件需要评估时,测试人员通常会选择 JUnit。JUnit 提供最佳的代码组织、更通用的代码修复和更好的错误检测。对于注重多功能性的组织,JUnit 提供了丰富的服务。它不仅简化了测试流程,还可以在整个系统的集成测试功能测试中使用。
  • Pytest:Pytest 轻松管理围绕 Python 编程语言构建的测试的编写和执行。Pytest 还可用于单元测试、集成测试、功能测试和端到端测试。它因提供对测试参数化的内置支持而受到认可,因此您可以使用不同的变量运行相同的测试,而无需重复编写代码。
  • xUnit:使用 C# 编程语言的开发人员通常采用主流开源单元测试框架 xUnit。开发人员认为其测试环境适用于生成测试组件所需的深度隔离。它甚至可以兼容其他测试工具,以实现无缝操作工作流。xUnit 的语法有助于简化测试创建。

AI 如何影响单元测试

现在人们普遍认识到,所有计算现在都处于过渡状态,正在被人工智能 (AI) 的处理能力所彻底改变。单元测试因 AI 而实现了其自身的优点:

  • 全面的测试覆盖范围:单元测试最重要的环节在于错误检测,AI 可以识别人类测试人员可能遗漏的错误。另外,AI 还可创建具备持续学习能力的“自我修复”测试——这是一项重大突破。
  • 加强测试编写:测试人员根据经常变化的情况和快速变化的需求来设定生产环境。幸运的是,AI 可以快速完成复杂的事情,例如开发单元测试套件以确保开发团队按计划完成工作。
  • 持续反馈:部署 AI 的优势之一,在于简化并加强开发环境的使用体验,乃至开发运维 (DevOps) 和 CI/CD 管道的效能。测试人员的直接回报是其能够获得持续反馈,从而缩短开发周期。
  • 专业测试分析:有了 AI,测试人员在运行何种测试方面有了更大的余地。例如,AI 可以执行根本原因分析来评估测试失败的根本原因。同样,AI 可以进行更复杂的测试,例如使用代码模式和历史数据来预测未来的测试故障,从而进行预测性测试故障分析。
相关解决方案
IBM Instana Observability

利用 AI 和自动化的强大功能,主动解决整个应用程序堆栈中的问题。

深入了解 IBM Instana Observability
DevOps 解决方案

使用开发运维软件和工具,在多种设备和环境中构建、部署和管理云原生应用程序。

探索 DevOps 解决方案
云咨询服务

通过我们的云咨询服务持续实现应用现代化,加速业务敏捷性与增长——支持任意平台部署。

深入了解我们的云咨询服务
采取后续步骤

从 IBM Instana® 的主动问题检测到跨堆栈实时洞察,让云原生应用程序保持高可靠运行。

  1. 了解 IBM Instana
  2. 探索 DevOps 解决方案