为什么需要自动测试?
以下是为什么我们应该拥有自动化测试的众多充分理由:
- 您可以更快地对代码进行增量更新。 ROS 有成百上千个包,且它们之间存在许多相互依赖关系,因此很难预料一个小的改动可能会引起什么问题。如果您的改动通过了单元测试,您就可以更有信心没有引入问题——或者至少问题不是您的过错。
- 您可以更有信心地重构代码。 通过单元测试可以验证您在重构过程中没有引入任何错误。这让您拥有不受“更改恐惧”束缚的自由!
- 它促使设计出更好的代码。 单元测试迫使您编写更易于测试的代码。这通常意味着保持底层函数与框架分离,这正是我们编写 ROS 代码的设计目标之一。
- 它们可以防止错误复发(错误回归)。 为每个修复的 bug 编写单元测试是一个好习惯。事实上,应该在修复 bug 之前编写单元测试。这将帮助您精确地、甚至确定性地重现 bug,并且更准确地理解问题的所在。因此,您也将创建更好的补丁,然后您可以使用回归测试来验证 bug 是否被修复。这样,如果以后代码被修改,bug 就不会意外地再次出现。这也意味着更容易说服补丁审查者问题已解决,并且贡献具有高质量。
- 其他人可以更容易地在您的代码上工作(一种自动化的文档形式)。 当您进行更改时,很难判断是否破坏了其他人的代码。单元测试是其他开发者验证其更改的工具。自动化测试记录了您的编码决策,并自动向其他开发者传达他们的违规行为。因此,测试成为您代码的文档——一种大多数时候无需阅读的文档,而当需要检查时,测试系统将精确指示要阅读什么(哪些测试失败)。通过编写自动化测试,您使其他贡献者更快。这改善了整个 ROS 项目。
- 如果我们有自动化单元测试,成为 ROS 的贡献者会容易得多。 新的外部开发者很难为您的组件做出贡献。当他们更改代码时,通常是在盲目地进行,靠大量的猜测。通过提供自动化测试的支撑,您可以协助他们完成任务。他们对自己的更改能获得即时反馈。这使得对项目的贡献更容易,新贡献者也能更轻松地加入。同时他们的首次贡献质量更高,这减少了维护者的工作量。双赢!
- 自动化测试简化了维护工作。 特别是对于成熟的包,它们变化较慢,主要需要更新以适应新的依赖关系,自动化测试套件有助于非常快速地确定包是否仍然正常工作。这使得决定包是否仍受支持变得更加容易。
- 自动化测试放大了持续集成的价值。 回归测试以及基于场景的常规需求测试,共同构成了组件自动化测试的整体。您的组件可以更好地抵御它所依赖的其他 API 的演变(CI 服务器将更好、更精确地告诉您代码中出现了什么问题)。
- 也许编写测试最重要的好处是,测试让您成为一个好公民。 测试从长远来看影响质量。这是许多开源项目中广为接受的做法。通过编写回归测试,您为 ROS 生态系统的长期质量做出了贡献。
这一切都是免费的吗?
当然,天下没有免费的午餐。要获得测试的好处,需要一些投入。
- 您需要开发一个测试, 这有时可能很困难或成本很高。有时也可能并不简单,因为测试应该是自动化的。如果您的测试需要涉及特殊硬件(不应该:尝试使用仿真、模拟硬件,或将测试缩小到更小的软件问题),或者需要外部环境,例如人工操作员,事情就会变得特别复杂。
- 回归测试和其他自动化测试需要维护。 当组件的设计发生变化时,许多测试会失效(例如它们不再编译,或者抛出与 API 设计相关的运行时异常)。这些测试失败不仅是因为重新设计重新引入了错误,还因为它们需要更新以适应新设计。偶尔,在进行较大的重新设计时,应该放弃旧的回归测试。
- 大量的测试可能需要很长时间才能运行, 这可能会增加持续集成服务器的成本。
可用教程:
- 从命令行在 ROS 2 中运行测试
- 使用 GTest 编写 C++ 基本测试
- 使用 Python 编写基本测试
- 使用 launch_testing 编写基本集成测试
- 在 ROS 构建农场中测试您的代码
本文档完整翻译自 ROS 2 Lyrical 官方文档,仅用于学习交流。
夜雨聆风