Unit testing with GoogleTest in ROS - AD-EYE/AD-EYE_Core GitHub Wiki

Introduction

Unit testing in ROS: http://wiki.ros.org/Quality/Tutorials/UnitTesting

Code Structure and CMakeLists

Code Structure

Create a folder for testing at root of the package: <package_root>/tests

Write test_n.cpp under the folder, for example, test_1.cpp, test_2.cpp... In order to initialize and run GoogleTest, include the following main function in one of them:

int main(int argc, char **argv){
   testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
}

Configure CMakeLists

For example, here we need to write tests for sensor_monitor.cpp, include the following in CMakeLists.txt.

...
...
add_library(sensorMonitor
  src/sensor_monitor.cpp
)
...
...
target_link_libraries(
  sensorMonitor
  ${catkin_LIBRARIES}
)
...
...
catkin_add_gtest(sensorMonitor-test tests/test_1.cpp)
...
...
target_link_libraries(sensorMonitor-test sensorMonitor)

If we add test_2.cpp, we only need to modify CMakeLists accordingly in catkin_add_gtest:

catkin_add_gtest(sensorMonitor-test tests/test_1.cpp tests/test_2.cpp)

Suggestions and Useful Links

Use Test Fixtures

If we need to test on a class with several tests, using test fixtures allows us to manage the setup and teardown process easily. More explanation for macros and supported features in GoogleTest are in http://google.github.io/googletest/primer.html.

An example of using test fixtures is here: test_2.cpp

Use FRIENDTEST to Access Private Attributes in test

In the declaration of the class, use FRIENDTEST to give access of the test cases to private attributes.

An example is here: sensor_fov.h

ROS Initialization and Passing Nodehandle

Sometimes, in the construct of the class we need to test needs to pass the nodehandle. Currently I used static variables, there might be a better solution. test_2.cpp

In other cases, we can initialize ros and create node handle in the main function of test_n.cpp.

int main(int argc, char** argv) {
    testing::InitGoogleTest(&argc, argv);
    ros::init(argc, argv, "test_talker");
    ros::NodeHandle nh;
    return RUN_ALL_TESTS();
}

Other Useful Links: