Robotics StackExchange | Archived questions

Is there a way to replace socket communication functions for unit testing?

I have a large source base with multiple contributors that runs a lot of unit tests on the server every time a PR is issued. I want to have more code coverage without creating a special interface for my nodes and classes and I've run into two problems:

  1. Some of my classes have a very limited interface that depend a lot on subscriber callback methods.

  2. Some of my classes publish its output directly to a topic.

The obvious solution is to use publishers and subscribers in a unit test to check this functionality. However, this will really slow down the testing process by incorporating socket communication in our unit tests.

Therefore, I would really like to find a way to replace the ROS subscribe and publish functions with my own, only for the purpose of testing. Is there an implementation for this or an easy way to do this? Has anybody already thought about this and determined its usefulness?

Asked by cpagravel on 2017-03-27 15:42:53 UTC

Comments

I don't think this is possible without some serious research into how those functions are used in the middleware layers.

I've seen some projects where "nodelet everything" was (ab)used for this: for testing, start everything as nodelets. Normal production system, load them as standalone nodes.

Asked by gvdhoorn on 2017-03-29 12:11:41 UTC

slow down the testing process by incorporating socket communication in our unit tests

(without trying to be pedantic here): wouldn't including socket comms immediately make these tests integration tests? Sockets are typically used to cross component barriers, implying multiple components are ..

Asked by gvdhoorn on 2017-03-29 12:13:12 UTC

.. involved in the test. To me that sounds like integration tests.

What I've seen done is to refactor things in such a way that either:

  • callbacks actually only dispatch to other (member) functions
  • callbacks are idempotent

in both cases that makes it easier to call those methods in proper ..

Asked by gvdhoorn on 2017-03-29 12:14:41 UTC

.. unit tests that don't depend on an entire ROS graph being present and functional.

Asked by gvdhoorn on 2017-03-29 12:15:32 UTC

Finally: you're probably aware of it, but rostest explicitly supports starting up (parts of a) ROS node graph to facilitate testing of components that 'need' it.

Asked by gvdhoorn on 2017-03-29 12:16:18 UTC

Thanks for the comments. I wasn't notified that someone had commented on this post. Can you define what an idempotent callback is? I'm only aware of the definition of idempotent as it relates to linear algebra :P. What I ended up doing was making the callbacks as protected functions and...

Asked by cpagravel on 2017-04-03 12:28:49 UTC

In my test case, I had a class that inherits the node class so I can call those callbacks directly (as if a message was passed to it). It is not ideal and it limited behaviour when spinOnce was called. For those cases I ended up using publishers as one would in the actual implementation.

Asked by cpagravel on 2017-04-03 12:31:30 UTC

I see that idempotence in computer science is very similar to the linear algebra definition. Anyway, my primary concern was about the speed of my unit tests, but it seems that, because this unit test was intended to recreate a race condition, I could not simplify it further.

Asked by cpagravel on 2017-04-03 12:38:13 UTC

Answers