ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
4

About unit testing in ROS2 - DI, wrappers and code structure.

asked 2023-05-02 07:19:01 -0600

Bernat Gaston gravatar image

Hi all,

Some time ago I used to be responsible of the testing framework of some software products outside of ROS. It's been some time that I am working in ROS now (lately in ROS2) and there are aspects on the testing design of ROS2 that I still don't understand. Specifically, I am talking about unit testing and the fact that many ROS2 functionalities are designed to use rclcpp:Node in an inheritance mode.

As far as I'm concerned in unit testing, you want to test (ideally one) aspect of you own code. This is why many libraries are using Dependency Injection instead of inheritance, to help developers test only their code. Hence, when you want to test, instead of the main library, you inject a mock and you can test your function without the need to call the library.

However, I see that the main code of ros2 and also the tests included use rclcpp:Node directly (without using mocks) and test multiple things (actually it seems that tests are most of the times integration ones and not unit ones). For example

https://github.com/ros2/rclcpp/blob/b...

Also, I tend to find the tests very long and difficult to follow, so I am a bit lost here. I assume I am not understanding something of the idea behind the testing architecture of ROS2. Why so inheritance based? Why testing so many things in a single function?

I have searched for a "testing guideline" or something like that but I am unable to find it. Can anybody enlighten this?

Many thanks

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2023-05-12 02:49:47 -0600

Vince gravatar image

Hi!

I completely agree with you that testing software in ROS2 is not so straightforward as we wish. There's just a little point that is not clear from your question. Are you referring to testing some library (ROS2 indipendent) or the ROS2 interface for that library?

As far as I've understood is more the latter. In such case I wouldn't suggest (in my opinion) to unit testing your ROS2 interface, but rather using integration testing, since your goal is to verify the communication of your node. Also doing this has some level of complexity. In practice I know there are just a couple of ways to do that:

edit flag offensive delete link more

Comments

Thanks for the answer. We were not using testing at all so I wanted to start testing our code and I thought unit testing would be the best starting point. My first objective was to test our code without the ROS2 dependencies, specially the class node. I agree that integration testing is probably a must have in some near future. Answering your question, as an example, I have a function that I want to test. This function, at the end of its logic, calls a class ROS2 publisher.publish to publish a message. All I want to test is my function and maybe the fact that it calls the publisher, but I am not worried about the fact that this message is actually published, since I trust ros2 to do the job. If I do this function in python I can mock it easily because the mock library is very ...(more)

Bernat Gaston gravatar image Bernat Gaston  ( 2023-05-14 04:07:01 -0600 )edit
1

My bad, I thought you wanted to test the ROS2 communication. In the case of unit testing your logic class then as you correctly said you need to make it indipendent from ROS2. This means that your logic class shoud not rely on any ROS2 functionality. Then the question is how to enable ROS2. An answer I've found (but there could be others) is through composition.

For C++ in practice, you'll have

  • a logic class: a classic C++ class that implements your logic, withouth any ROS publisher, ecc...

  • a ROS2 interface class: a class that inherits rclpcpp::Node and instanciates an object of your logic class, as well as initializating all the ROS2 objects needed.

In this way you can perform unit testing on your logic class without involving ROS2. Another adantage is that the lifecycle of the object is handled enterily by the ROS2 interface class.

Vince gravatar image Vince  ( 2023-05-14 09:03:40 -0600 )edit

That makes a lot of sense. Thanks!

Bernat Gaston gravatar image Bernat Gaston  ( 2023-05-15 04:19:31 -0600 )edit

Question Tools

5 followers

Stats

Asked: 2023-05-02 07:19:01 -0600

Seen: 871 times

Last updated: May 12 '23