In order to create our package we have used the following commands:
mkdir ~/catkin_ws/src -p
cd ~/catkin_ws/src
catkin_create_pkg tutorial rospy
cd tutorial/
mkdir test
cd test/
touch test_code.py
chmod +x test_code.py
ls
The content of our test_code.py file is:
#! /usr/bin/env python
import unittest
import rostest
class MyTestCase(unittest.TestCase):
def test_whatever(self):
pass
if __name__ == “__main__”:
rostest.rosrun(‘tutorial’, ‘test_code’, MyTestCase)
The first way of executing it is by calling it directly:
./test_code.py
The second way is using a .test file:
roscd tutorial
mkdir launch
cd launch/
touch test_code.test
After filling that file we call it with:
rostest tutorial test_code.test
The 3rd way of executing is by adding the line below to our CMakeLists.txt file:
catkin_add_nosetests(test/test_code.py)
and calling:
cd ~/catkin_ws/
catkin_make run_tests
And the 4th way is by adding the lines below to our CMakeLists.txt file (remove to remove the line added on the 3rd way, otherwise
your test will be executed twice, wasting time):
It goes without saying that when we are developing, despite everything be seemingly working as expected, sometimes as soon as we put on production we see that the code doesn’t really work as expected.
One of the best ways to avoid problems like the aforementioned one is by having Unit Tests, therefore, in today’s videos we are going to learn how to run a Unit Test that ensures a parameter has been successfully loaded on the ROS Parameter Server. For that we are going to use Robot Ignite Academy, which is the best platform for those who want to Learn ROS Fast.
But before we start, if you are new to ROS, keep in mind that we offer the following ROS Basics courses:
Let’s suppose in our scenario we load ROS Parameter files from different ROS Packages we want to make sure they load as expected. For that, we first need to create a package called tutorial on our ~/catkin_ws/src folder, which can be accomplished with the following commands:
mkdir ~/catkin_ws/src/ -p
cd ~/catkin_ws/src/
catkin_create_pkg tutorial rospy
Now that our package was successfully created, let’s create a launch file called load_params.launch inside the launch folder by using the commands below:
cd ~/catkin_ws/src/tutorial/
mkdir launch
touch launch/load_params.launch
The file we just created will be used to load the ROS parameters. Since we don’t have parameter file, let’s try to find one on the ROS folders. For that let’s type:
find /opt/ros/kinetic/ -name *.yaml | head
After running the command above we may have ~10 lines in the output. We are only interested in a single file, so, let’s take the first line, which in my system was:
By looking at that file we see that we have a parameter called value with the value 10:
value: 10
If we just try to get a variable called value from the ROS Parameter server we can see that the variable doesn’t exist, since we didn’t load that file yet. Let’s confirm with the command below:
rosparam get /value
we should have the following output:
ERROR: Parameter [/value] is not set
Ok, so far so good. Let’s now modify our load_params.launch file in order to load that nodelet_tutorial_math/plus_default.yaml file. For that, let’s paste the following content on our launch file:
If we now try to get that parameter from the ROS Parameter Server we should see the value 10. Let’s do it with the next command:
rosparam get /value
Ok, since we know everything is working when we manually run the commands, let’s now remove that parameter again from the server to test in an automated way. To remove it, use the following command:
rosparam delete /value
The reason why we might need a test is because our project starts increasing, we start loading parameters from different packages, loading different launch files, so on and so forth.
In order to create a our test, let’s create a test folder inside our package with a file named test_params.py inside. Let’s use the following commands for that:
cd ~/catkin_ws/src/tutorial/
mkdir test
cd test
touch test_params.py
chmod +x test_params.py
Ok, now let’s create our Unit Test. For that, let’s paste the following content on the test_params.py file:
#! /usr/bin/env python
import unittest
import rospy
import rostest
class MyTestCase(unittest.TestCase):
def test_param_loaded(self):
value = rospy.get_param('/value', None)
self.assertIsNotNone(value)
if __name__ == '__main__':
rostest.rosrun('tutorial', 'test_params', MyTestCase)
If we just run this test now we will see that it will fail because we don’t have the parameter loaded. Let’s run it to confirm that:
rosrun tutorial test_params.py
The test output should show a failure, something like the message below:
[ROSUNIT] Outputting test results to /home/user/.ros/test_results/tutorial/rosunit-test_params.xml
[Testcase: test_param_loaded] ... FAILURE!
FAILURE: unexpectedly None
File "/usr/lib/python2.7/unittest/case.py", line 329, in run
testMethod()
File "/home/user/catkin_ws/src/tutorial/test/test_params.py", line 11, in test_param_loaded
self.assertIsNotNone(value)
File "/usr/lib/python2.7/unittest/case.py", line 960, in assertIsNotNone
self.fail(self._formatMessage(msg, standardMsg))
File "/usr/lib/python2.7/unittest/case.py", line 410, in fail
raise self.failureException(msg)
--------------------------------------------------------------------------------
-------------------------------------------------------------
SUMMARY:
* RESULT: FAIL
* TESTS: 1
* ERRORS: 0 []
* FAILURES: 1 [test_param_loaded]
In order to load the parameters automatically during test, we need a launch file that launches both our test_params.py and the load_params.launch we created earlier. The launch file we will create will have the .test extension but it is going to be a normal XML file, just as our .launch files.
To create it, just use these commands:
cd ~/catkin_ws/src/tutorial/launch/
touch load_params.test
Let’s put the following content on the file we just created in order be able to launch our test properly:
If we run that file now, our test should pass because the load_params.launch file will be included before running the test. Let’s test it:
rostest tutorial load_params.test
The log messages should show that the test has succeeded, something like:
[ROSUNIT] Outputting test results to /home/user/.ros/test_results/tutorial/rostest-launch_load_params.xml
[Testcase: testtest_params] ... ok
[ROSTEST]-----------------------------------------------------------------------
[tutorial.rosunit-test_params/test_param_loaded][passed]
SUMMARY
* RESULT: SUCCESS
* TESTS: 1
* ERRORS: 0
* FAILURES: 0
So, that is it for today, guys. I hope you liked the post.
Remember that below we also have the video that shows everything detailed in this post.
Also, feel free to post questions or suggestions on the comments section of the video on YouTube (https://www.youtube.com/watch?v=M_Vr0zJbih4) as well as share this content with your friends.
In this video, we’ll see how to create and launch a custom world in Gazebo. We’ll build the outline of a room that you’ll hopefully complete (in case you want to have some fun)!
If you are a ROS beginner and want to learn ROS basics fast, we recommend you take any of the following courses on Robot Ignite Academy:
Links mentioned in the video and other useful links:
– Robot Ignite Academy, the place to learn to program robots using only a web browser
– ROS Development Studio (ROSDS), a powerful online tool for pushing your ROS learning in a practical way (the environment used in the video for demonstration)