Ros Testing Tutorial

55
A Gentle Introduction to Gtest Víctor González Pacheco [email protected] March 2014 Test Driven Development in ROS

description

A tutorial about Testing in ROS that I gave to the members of my lab. Code Examples and Exercises in: https://github.com/VGonPa/ros-testing-tutorial

Transcript of Ros Testing Tutorial

Page 1: Ros Testing Tutorial

A Gentle Introduction to Gtest

Víctor González [email protected]

March 2014

Test Driven Development in ROS

Page 2: Ros Testing Tutorial

OutlineWhat to expectMotivationTesting LevelsWriting your first testsAdvice on making good testsResourcesExercise

Page 3: Ros Testing Tutorial

Start with an example

Download material at:https://github.com/VGonPa/ros-testing-seminar

git clone https://github.com/VGonPa/ros-testing-seminar.git

Page 4: Ros Testing Tutorial

What to expectfrom this seminar

Page 5: Ros Testing Tutorial

What to expect

“Will I become a TDD master with this seminar?”

Page 6: Ros Testing Tutorial

“Actually you might, eventually,if you start writing tests today!”

Page 7: Ros Testing Tutorial

What to expect

You will learn where to start,the basics, and where to find more

information and help.

Page 8: Ros Testing Tutorial

Motivation

Page 9: Ros Testing Tutorial

Motivation

"Tests + Programming" is faster than just "Programming" [1]

Page 10: Ros Testing Tutorial

MotivationSW Evolves

Requirements changeBug correctionsOptimizationsImprovements on design

How do you know if a change in your code didn’t break your previous work?

Page 11: Ros Testing Tutorial

MotivationNOT testing is very dangerous:

“(Making large changes without tests) is like doing aerial gymnastics without a net.” [1]

The later you detect a bug, the more expensive is to fix it:

A bug detected in production may be REALLY expensiveLet alone if tomorrow you have a demo!

Page 12: Ros Testing Tutorial

MotivationSome advantages of writing testsIt forces you to design better code

Faster incremental upgrades

A clear metric of your progress

It lets you refactor with greater confidence

Prevents recurring bugs

It enables you to blame others!

Other people can work with your code more easily

Page 13: Ros Testing Tutorial

MotivationThe worst disadvantage

It will affect your thinking process......and your programming style.

But you will become a better programmer!

Page 14: Ros Testing Tutorial

Motivation

“I don’t have time to write tests!”

Had you done the tests before, now you'd have time to do them!

More tests = less time debuggingMore tests = more time to program features

Page 15: Ros Testing Tutorial

Test Driven Development (TTD)The process

Before programming, write tests

Write only the needed code to make the tests pass

Refactor to eliminate duplicated code, etc.

Repeat

Page 16: Ros Testing Tutorial

Test Driven Development (TTD)

“Do I really need to write tests first?”

It’s much better to write them first,but if you don’t, be sure that your code is properly tested

Page 17: Ros Testing Tutorial

Testing Levels

Page 18: Ros Testing Tutorial

Imagine a simple scenario

N1 N2

Page 19: Ros Testing Tutorial

Each node has its own code...

N1 N2

Page 20: Ros Testing Tutorial

This is better...

N1 N2

Page 21: Ros Testing Tutorial

There you have the first level

N1 N2

Library Unit Testing

Page 22: Ros Testing Tutorial

Library Unit testing

N1

Library Unit Testing Test only your libraries

Code must be ROS Agnostic

GTest/Unittest(python)

Page 23: Ros Testing Tutorial

Library Unit testing

N1Test each component separately

Page 24: Ros Testing Tutorial

Library Unit Testing

N1

Test for:

common cases

extreme cases

Input errors

methods pre and post conditions

Page 25: Ros Testing Tutorial

Now let’s test the node itself

N1 N2

Node LevelTesting

Page 26: Ros Testing Tutorial

Node Level Unit testing

N1

Node LevelTesting

Test Node start/shutdown

Test Node external APIservices, published topics, subscribed topics (params?)

RosTest + GTest/Unittest

Page 27: Ros Testing Tutorial

And, finally, the whole system

N1 N2

Integration/Regression Testing

Page 28: Ros Testing Tutorial

Integration Testing

N1 N2

Test multiple nodes working as expected

RosTest + GTest/Unittest

Page 29: Ros Testing Tutorial

Testing Levels: Overview

N1 N2

Library UnitTesting

Node LevelTesting

Integration/Regression Testing

Page 30: Ros Testing Tutorial

Writing your first testsin ROS

Page 31: Ros Testing Tutorial

Gtest and rostest

ROS provides two tools for executing tests:

gtest and rostest

Page 32: Ros Testing Tutorial

GTestGoogle’s tool for unit testing

Regular cpp files

Executed with any of the following: ./my_test_file

make test # needs macro in CMakeLists.txt

rosmake <package_name> -t # needs macro in CMakeLists.txt

http://wiki.ros.org/gtest

Gtest and rostest

Page 33: Ros Testing Tutorial

GTest

Gtest tutorials are quite good. We won’t cover them here.Read them if you don’t know how to write Gtests.

Gtest and rostest

Page 34: Ros Testing Tutorial

Gtest and rostestrostest

roslaunch extension to launch tests

.launch syntax with added <test> tag

executed with any of the following: rostest <pgk_name> <test_name>.test

make test # needs macro in CMakeLists.txt

rosmake <package_name> -t # needs macro in CMakeLists.txt

http://wiki.ros.org/rostesthttp://wiki.ros.org/rostest/Writinghttp://wiki.ros.org/roslaunch/XML/test <------ <test> tag reference

Page 35: Ros Testing Tutorial

Where should I use each one?

N1 N2

Node

Integration/Regression

Library

GtestRostest (+ Gtest)

Page 36: Ros Testing Tutorial

Package structure with tests

my_ros_pkg/

CMakeLists.txt

bin/

build/

msg/

...

src/

test/ <--- gtests go here

test/ <--- rostests go here

Page 37: Ros Testing Tutorial

InstallationGTestInstall: bash> sudo apt-get install libgtest-devIn your header files:

#include <gtest/gtest.h>

GMockInstall bash> sudo apt-get install google-mock

In your header files:#include <gmock/gmock.h>

Page 38: Ros Testing Tutorial

Gtest CMakeLists.txt

# add gtest

rosbuild_add_gtest(test/my_test test/mytest.cpp

[other sources])# link required libraries

target_link_libraries(test/mytest linked_libraries)

Page 39: Ros Testing Tutorial

rostest CMakeLists.txt

# add the test executable,

# keep it from being built by "make all"

rosbuild_add_executable(test_mynode EXCLUDE_FROM_ALL

src/test/test_mynode.cpp)

# Link test_mynode against gtest

# and add a dependency to the "test" target

rosbuild_add_gtest_build_flags(test_mynode)

# Make sure rostest launches test/mynode.test during "make test"

rosbuild_add_rostest(test/mynode.test)

Page 40: Ros Testing Tutorial

Let’s see an example

Checkout the package rostest_node_example from the material

Page 41: Ros Testing Tutorial

Some adviseHow to make good tests

Page 42: Ros Testing Tutorial

What to testExample: max(list_of_ints)

Normal casesmax([10,3,0,-1,8])

Extreme casesmax([3,3,3,3,3,3])

max(2)

Error casesmax([‘aaa’,3,nan,None])

max([])

Page 43: Ros Testing Tutorial

What not to testThe test itselfModules that cannot be broken (or that there is no solution):

System callsHardware failures

Modules from which your code depends on:Standard Libraries, modules written by others, etc.

They already have (or should have) their own tests

Exhaustive tests

Page 44: Ros Testing Tutorial

Writing more “testable” codeSometimes it’s difficult to test a component in isolation

Dependencies between components

Some components might be on the network (eg. sockets)

Some components might needuser input

Some comopnents might just be slow to test

Page 45: Ros Testing Tutorial

Writing more “testable” code

Solution: Break dependencies

Program against interfaces

Specify dependencies in the constructor

Use mocks in your tests

Page 46: Ros Testing Tutorial

Common features of good testsA good test should be:

Independent1. You do not need to read other tests to understand what a test does2. If a test fails, it should be easy to find the bug3. Each test focuses on a single aspect

Repetible

Quick: Use mocks

Small: Enables you to easily spot bugs. Big tests functions have many parts affecting each other

Page 47: Ros Testing Tutorial

Beware the Unit-Integration Chimera!

Unit TestingSweet spot

Integration TestingSweet spot

It will eat your productivity!

Page 48: Ros Testing Tutorial

Bibliography and Resources

Page 49: Ros Testing Tutorial

Bibliography and ResourcesB. Eckel, "Thinking in C++ Volume 2". (online version)

Google C++ Testing Framework projectProject: http://code.google.com/p/googletest/

Guía inicial: http://code.google.com/p/googletest/wiki/V1_6_Primer

Avanzado: http://code.google.com/p/googletest/wiki/V1_6_AdvancedGuide

Ejemplos: http://code.google.com/p/googletest/wiki/V1_6_Samples

Dependency injection, mocks: Google Mock: http://code.google.com/p/googlemock/

Page 50: Ros Testing Tutorial

Bibliography and ResourcesROS Unit Testing: http://wiki.ros.org/UnitTesting

ROS GTest: http://wiki.ros.org/gtest

ROS rostest: http://wiki.ros.org/rostest

Page 51: Ros Testing Tutorial

Bibliography and ResourcesThis seminar has been greatly inspired from this talk from Zhanyong Wan:

Effective C++ Testing Using Google Test

There you will find more information regarding Gtest and Unit testing in general

Page 52: Ros Testing Tutorial

Questions?https://github.com/VGonPa/ros-testing-seminar

Page 53: Ros Testing Tutorial

Excercise

Page 54: Ros Testing Tutorial

1. Counter node’s counter should be initiated by parameter to any number

2. Factorial calculates factorial of counter3. Test the library, node and integration using gtest +

rostests

counter_node factorial_node

/counter /factorial/do_increment

Page 55: Ros Testing Tutorial

This seminar is licensed under the Creative Commons license CC Attribution 4.0 International

You are free to use and adapt this presentation as long as you give credit to the author.More information can be found here:

http://creativecommons.org/licenses/by/4.0/