【ROS2】测试

 为什么要进行自动化测试?

以下是我们应该进行自动化测试的许多重要原因之一:

  • 您可以更快地对代码进行增量更新。ROS 有数百个包,具有许多相互依赖关系,因此很难预见一个小变化可能引起的问题。如果您的更改通过了单元测试,您可以更有信心地认为您没有引入问题——或者至少问题不是您的错。

  • 您可以更自信地重构代码。通过单元测试可以验证您在重构时没有引入任何错误。这让您摆脱了对变化的恐惧,获得了这种美妙的自由!

  • 它导致更好的代码设计。单元测试迫使你编写代码,使其更容易测试。这通常意味着保持底层函数和框架分离,这是我们设计 ROS 代码的目标之一

  • 他们防止重复出现的错误(错误回归)。为你修复的每个错误编写单元测试是一个好习惯。事实上,在修复错误之前编写单元测试。这将帮助你精确地,甚至是确定性地重现错误,并更精确地理解问题所在。结果,你还将创建一个更好的补丁,然后可以使用回归测试来验证错误是否已修复。这样,如果代码在以后被修改,错误就不会意外地重新引入。这也意味着说服补丁审查员问题已解决,并且贡献质量很高会更容易。

  • 其他人可以更容易地处理你的代码(自动文档形式)。当你进行更改时,很难判断你是否破坏了别人的代码。单元测试是其他开发人员验证其更改的工具。自动测试记录你的编码决策,并自动向其他开发人员传达其违规行为。因此,测试成为你的代码的文档——一种大多数时间不需要阅读的文档,当需要检查时,测试系统会准确指示需要阅读的内容(哪些测试失败)。通过编写自动测试,你使其他贡献者更快。这改善了整个 ROS 项目。

  • 如果我们有自动化单元测试,成为 ROS 的贡献者会容易得多。对于新的外部开发人员来说,向您的组件做出贡献是非常困难的。当他们对代码进行更改时,通常是在盲目操作,依靠大量的猜测。通过提供自动化测试的工具,您可以帮助他们完成任务。他们会立即获得更改的反馈。这样更容易为项目做出贡献,新贡献者也更容易加入。此外,他们的首次贡献质量更高,从而减少了维护人员的工作量。这是双赢的局面!

  • 自动测试简化了维护工作。特别是对于变化较慢的成熟软件包,主要需要更新到新的依赖项,自动测试套件有助于快速确定软件包是否仍然有效。这使得决定软件包是否仍然受支持变得更加容易。

  • 自动测试放大了持续集成的价值。回归测试以及基于正常场景的需求测试,有助于为您的组件提供整体的自动化测试。您的组件在依赖的其他 API 演变过程中得到了更好的测试(CI 服务器将更好、更准确地告诉您代码中出现的问题)。

也许编写测试最重要的好处是测试使你成为一个好公民。测试从长远来看会影响质量。这是许多开源项目中广泛接受的做法。通过编写回归测试,你正在为 ROS 生态系统的长期质量做出贡献。

这一切都是免费的吗?

当然,天下没有免费的午餐。要获得测试的好处,必须进行一些投资。

  • 您需要开发一个测试,这有时可能会很困难或昂贵。有时它也可能并非易事,因为测试应该是自动化的。如果您的测试涉及特殊硬件(不应该:尝试使用模拟、模拟硬件或将测试缩小到较小的软件问题)或需要外部环境,例如人类操作员,事情会变得特别棘手。

  • 回归测试和其他自动测试需要维护。当组件的设计发生变化时,许多测试会失效(例如,它们不再编译,或抛出与 API 设计相关的运行时异常)。这些测试失败不仅是因为重新设计重新引入了错误,还因为它们需要更新到新的设计。偶尔,对于较大的重新设计,旧的回归测试应该被删除。

  • 大量的测试可能需要很长时间才能运行,这会增加持续集成服务器的成本。

 可用教程:

  • 从命令行运行 ROS 2 测试

  • 使用 GTest 编写 C++ 基本测试

  • 用 Python 编写基本测试

从命令行运行 ROS 2 测试

构建并运行你的测试

要编译和运行测试,只需从 colcon 运行测试动词 https://colcon.readthedocs.io/en/released/reference/verb/test.html 。

colcon test --ctest-args tests [package_selection_args]

(其中 package_selection_args 是 colcon 的可选包选择参数,用于限制构建和运行的包)

在测试之前获取工作区应该是不必要的。 colcon test 确保测试在正确的环境中运行,能够访问它们的依赖项等。

 检查测试结果

要查看结果,只需从 colcon 运行 test-result 动词。https://colcon.readthedocs.io/en/released/reference/verb/test-result.html

colcon test-result --all

要查看确切的失败测试用例,请使用 --verbose 标志:

colcon test-result --all --verbose

使用 GDB 调试测试

有关使用 GDB 调试测试的详细指南,请参阅 GDB 教程 https://docs.ros.org/en/jazzy/How-To-Guides/Getting-Backtraces-in-ROS-2.html 。

使用 GTest 编写 C++ 基本测试

起点:我们假设您已经设置了一个基本的 ament_cmake 包,并且您想要添加一些测试。

在本教程中,我们将使用 gtest。https://google.github.io/googletest/primer.html

 程序包设置

 源代码 

我们将从一个名为 test/tutorial_test.cpp 的文件中的代码开始

#include <gtest/gtest.h>TEST(package_name, a_first_test)
{ASSERT_EQ(4, 2 + 2);
}int main(int argc, char ** argv)
{testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

 package.xml

将以下行添加到 package.xml

<test_depend>ament_cmake_gtest</test_depend>

 CMakeLists.txt

if(BUILD_TESTING)find_package(ament_cmake_gtest REQUIRED)ament_add_gtest(${PROJECT_NAME}_tutorial_test test/tutorial_test.cpp)target_include_directories(${PROJECT_NAME}_tutorial_test PUBLIC$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>$<INSTALL_INTERFACE:include>)target_link_libraries(${PROJECT_NAME}_tutorial_test name_of_local_library)
endif()

测试代码被包装在 if/endif 块中,以尽可能避免构建测试。 ament_add_gtest 的功能类似于 add_executable ,因此您需要像往常一样调用 target_include_directories 、 ament_target_dependencies 和 target_link_libraries 。

 运行测试

请参阅有关如何从命令行运行测试 https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Testing/CLI.html 的教程,以获取有关运行测试和检查测试结果的更多信息。

用 Python 编写基本测试

起点:我们假设您已经设置了一个基本的 ament_python 包,并且您想为其添加一些测试。

如果您使用 ament_cmake_python,请参阅 ament_cmake_python 文档以了解如何使测试可发现。测试内容和使用 colcon 的调用保持不变。

 程序包设置

setup.py

您的 setup.py 必须在调用 setup(...) 时对 pytest 有测试依赖:

tests_require=['pytest'],

测试文件和文件夹

您的测试代码需要放在包根目录中名为 tests 的文件夹中。

任何包含您要运行的测试的文件必须具有模式 test_FOO.py ,其中 FOO 可以替换为任何内容。

示例包布局:
awesome_ros_package/awesome_ros_package/__init__.pyfozzie.pypackage.xmlsetup.cfgsetup.pytests/test_init.pytest_copyright.pytest_fozzie.py

 测试内容

您现在可以尽情编写测试了。关于 pytest 有很多资源,但简而言之,您可以编写带有 test_ 前缀的函数,并包含您想要的任何断言语句。

def test_math():assert 2 + 2 == 5   # This should fail for most mathematical systems

 运行测试

请参阅有关如何从命令行运行测试的教程,以获取有关运行测试和检查测试结果的更多信息。

 特殊命令

除了标准的 colcon 测试命令外,您还可以使用 --pytest-args 标志从命令行向 pytest 框架指定参数。例如,您可以指定要运行的函数名称。

colcon test --packages-select <name-of-pkg> --pytest-args -k name_of_the_test_function

要在运行测试时查看 pytest 输出,请使用以下标志:

colcon test --event-handlers console_cohesion+

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/46352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

语言主要是一种交流工具,而不是思维工具?GPT5何去何从?

引言 在人工智能领域&#xff0c;特别是大语言模型&#xff08;LLM&#xff09;的发展中&#xff0c;语言和思维的关系一直是一个备受关注的话题。近期&#xff0c;麻省理工学院&#xff08;MIT&#xff09;在《Nature》杂志上发表了一篇题为《Language is primarily a tool f…

Unity踩坑之RectTransformUtility.ScreenPointToLocalPointInRectangle

此方法会将屏幕坐标点转换为UI的本地坐标点&#xff0c;即UI子物体相对于父物体的相对位置。不过值得注意的是&#xff1a;当父物体的锚点不在中心时&#xff0c;可能比较麻烦&#xff0c;因为UI的本地坐标是相对于父物体的锚点来计算的。 RectTransformUtility.ScreenPointToL…

linux进程——概念理解与PCB

前言&#xff1a;本篇讲解Linux进程概念相关内容。 操作系统被称为计算机世界的哲学&#xff0c; 可以见得操作系统的知识并不好理解。 对于这篇进程概念的讲解&#xff0c; 博主认为&#xff0c; 如果没有一些前置知识的话&#xff0c;里面的有些概念并不好理解。 但是如果学习…

SQL Server 用户应当如何防范 Mallox (.hmallox) 勒索软件袭击

勒索软件领域的特点是随着时间的流逝&#xff0c;参与者群体和恶意软件家族都会大量流失&#xff0c;只有少数参与者表现出相对长寿的寿命。曾经令人担忧的威胁&#xff0c;如 REvil 和 Conti&#xff0c;要么被铲除&#xff0c;要么被解散&#xff0c;而其他威胁——例如 ALPH…

UGUI优化篇(更新中)

UGUI优化篇 1. 基础概念2. 重要的类1. MaskableGraphic类继承了IMaskable类2. 两种遮罩的实现区别RectMask2DMask 3. 渲染部分知识深度测试深度测试的工作原理 渲染队列透明物体在渲染时怎么处理为什么透明效果会造成性能问题 1. 基础概念 所有UI都由网格绘制的如image由两个三…

Leetcode(经典题)day4

滑动窗口 长度最小的子数组 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 使用滑动窗口&#xff0c;当前窗口大小的数组的和比目标值小就加大窗口&#xff08;r&#xff09;&#xff0c;当前窗口大小的数组的和比目标值大或相等&#xff0c;就减小窗口大小…

力扣题解(不同的子序列)

115. 不同的子序列 给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数&#xff0c;结果需要对 109 7 取模。 思路&#xff1a; 本题研究的是t在s中出现的次数&#xff0c;注意t一定是小的那个&#xff0c;是s的子串。 dp[i][j]表示t的&#xff…

25届平安产险校招测评IQ新16PF攻略:全面解析与应试策略

尊敬的读者&#xff0c;您好。随着平安产险校招季的到来&#xff0c;许多应届毕业生正积极准备着各项测评。本文旨在提供一份详尽的测评攻略&#xff0c;帮助您更好地理解平安产险的校招测评流程&#xff0c;以及如何有效应对。 25届平安产险平安IQ&#xff08;新&#xff09;测…

AI大模型探索之旅:深潜大语言模型的训练秘境

在人工智能的浩瀚星空中&#xff0c;大语言模型无疑是最耀眼的星辰之一&#xff0c;它们以无与伦比的语言理解与生成能力&#xff0c;引领着智能交互的新纪元。本文将带您踏上一场探索之旅&#xff0c;深入大语言模型的训练秘境&#xff0c;揭开其背后复杂而精妙的全景画卷。 …

Java常用API---Object类

Object类概述 概述 Object类是所有类的父类&#xff0c;任何一个类的对象(包括数组)&#xff0c;都可以调用Object类的方法 目标: 掌握Object类的常用方法 常用方法&#xff1a; boolean equals(Object obj)&#xff1a;判断当前对象是否与参数对象"相等" Strin…

Linux时间查看和设置

查看时间 date 命令&#xff0c;输出 Sun Jul 14 07:23:03 PM CST 2024timedatectl 命令&#xff0c;输出 Local time: Sun 2024-07-14 10:30:00 CSTUniversal time: Sun 2024-07-14 02:30:00 UTCRTC time: Sun 2024-07-14 02:30:00Time zone: Asia/Shanghai (CST, 0800) Sys…

汇编学习基础知识【记录】

前言 又是快乐的学习汇编的一天&#xff0c;时间如白驹过隙&#xff0c;抓紧时间&#xff0c;在学习能力最好的年纪多学习一些知识&#xff0c;朝着美好生活而奋斗&#xff01;哈哈哈 参考文章&#xff1a; https://blog.csdn.net/Z_H_Z_0/article/details/106574292 知识补…

给 「大模型初学者」 的 LLaMA 3 核心技术剖析

编者按&#xff1a; 本文旨在带领读者深入了解 LLaMA 3 的核心技术 —— 使用 RMSNorm 进行预归一化、SwiGLU 激活函数、旋转编码&#xff08;RoPE&#xff09;和字节对编码&#xff08;BPE&#xff09;算法。RMSNorm 技术让模型能够识别文本中的重点&#xff0c;SwiGLU 激活函…

现在有哪些微服务解决方案?

Dubbo&#xff1a;是一个轻量级的Java微服务框架&#xff0c;最初由阿里巴巴在2011年开源。它提供了服务注册与发现、负载均衡、容错、分布式调用等。Dubbo更多的被认为是一种高性能的RPC框架&#xff08;远程过程调用&#xff09;&#xff0c;一些服务治理功能依赖第三方组件完…

以一个springboot项目中创建用户会话的业务背景来说明threadlocal的用法

在Spring Boot项目中&#xff0c;ThreadLocal 是一个非常有用的工具&#xff0c;特别是在处理用户会话信息时。ThreadLocal 允许你在同一个线程中存储和访问变量&#xff0c;而不会与其他线程的变量发生冲突。这对于存储用户会话信息、请求上下文等非常有用。 以下是一个示例&…

第一部分:C++入门

目录 前言 1、C关键字(C98) 2、命名空间 2.1、命名空间定义 2.2、命名空间的使用 3、C输入&输出 4、缺省参数 4.1、缺省参数的概念 4.2、缺省参数的分类 5、函数重载 5.1、函数重载的概念 5.2、C支持函数重载的原理 6、引用 6.1、引用的概念 6.2、引用特性 …

Unity与Unreal Engine:AR建筑应用开发之选

在AR技术的浪潮中&#xff0c;建筑行业正迎来一场技术革新。对于希望为建筑工人开发AR应用的创业者来说&#xff0c;选择正确的开发平台至关重要。本文将基于社区讨论&#xff0c;深入分析Unity与Unreal Engine两款引擎在AR施工应用中的优劣&#xff0c;为开发者提供决策参考。…

深圳晶彩智能JC3636W518C开箱实现电脑副屏功能

深圳晶彩智能发布了JC3636W518C 这是一款中国制造的&#xff0c;铝合金外壳&#xff0c;价格非常震撼的开发板。原创是billbill的up播主萨纳兰的黄昏设计的ESP32太极小派&#xff0c;由深圳晶彩智能批量生产。 该款 LCD 模块采用 ESP32-S3R8 芯片作为主控,该主控是双核 MCU&…

LightDM和SDDM显示管理器学习小知识

LightDM和SDDM是两种不同的显示管理器&#xff08;Display Manager&#xff09;&#xff0c;它们可以与多种Linux桌面环境配合使用。以下是它们常见的对应关系&#xff1a; ### LightDM LightDM是一个跨桌面的显示管理器&#xff0c;它允许用户选择不同的桌面环境。以下是一些…

C++入门基础篇(2)

欢迎大家的来到小鸥的博客&#xff0c;今天我们继续C基础的第二篇吧&#xff01; 这也是入门基础篇的最后一篇wo~ 目录 1.引用 引用的概念 引用的特性及使用 const常引用 指针和引用的关系 2.inline内联函数 定义 相关特性及使用​ 3.nullptr >>后记<< …