• 【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 的文件中的代码开始

    1. #include
    2. TEST(package_name, a_first_test)
    3. {
    4. ASSERT_EQ(4, 2 + 2);
    5. }
    6. int main(int argc, char ** argv)
    7. {
    8. testing::InitGoogleTest(&argc, argv);
    9. return RUN_ALL_TESTS();
    10. }

     package.xml

    将以下行添加到 package.xml

    <test_depend>ament_cmake_gtesttest_depend>

     CMakeLists.txt

    1. if(BUILD_TESTING)
    2. find_package(ament_cmake_gtest REQUIRED)
    3. ament_add_gtest(${PROJECT_NAME}_tutorial_test test/tutorial_test.cpp)
    4. target_include_directories(${PROJECT_NAME}_tutorial_test PUBLIC
    5. $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    6. $<INSTALL_INTERFACE:include>
    7. )
    8. target_link_libraries(${PROJECT_NAME}_tutorial_test name_of_local_library)
    9. 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 可以替换为任何内容。

    示例包布局:
    1. awesome_ros_package/
    2. awesome_ros_package/
    3. __init__.py
    4. fozzie.py
    5. package.xml
    6. setup.cfg
    7. setup.py
    8. tests/
    9. test_init.py
    10. test_copyright.py
    11. test_fozzie.py

     测试内容

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

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

     运行测试

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

     特殊命令

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

    colcon test --packages-select  --pytest-args -k name_of_the_test_function

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

    colcon test --event-handlers console_cohesion+
  • 相关阅读:
    2024届秋招小记
    AMD(锐龙)处理器解决安装 AndroidStudio 虚拟机失败问题
    1027推免分享材料 备份
    数组扁平化(es6)
    从本地到Gitee:一步步学习文件上传及解决常见报错问题
    HDF5文件数据读取
    6-1应用层-网络应用模型
    算法:堆排序
    基于Highcharts平台的桑基图(Sankey diagram)绘制
    Docker高级-4.可视化工具Portainer/容器监控之CAdvisor+InfluxDB+Granfana
  • 原文地址:https://blog.csdn.net/cxyhjl/article/details/140412197