Design for testability

The system characteristic "testability" describes if a system or software can be tested and if so how easy. In software development general principles and best practices have been established to improve the testability of software. This section refers general principles and patterns which enable or improve the testability of the ROS library level code. In addition to that we try to apply best practices into the ROS node level.

Common principles and patterns

This section gives a short introduction into general principles and patterns which can be considered w.r.t. "common" production code design (design and Design Patterns). In addition to that Design for Testability principles and patterns are introduced which address enabling or improving testability in a way which is usually not achieved with production code Design Patterns alone.

TODO - overview over usual production code design considerations TODO - overview over design for testability patterns

Applying Design for Testability to ROS

This section shows how Design for Testability principles and patterns can be applied to ROS.

Break the dependency on real sensors

A ROS node which encapsulates sensor functionality will usually depend on one or several classes which abstract the sensors functionality. This classes depend on the sensor and will not function without having the sensor running.

If you want to verify the functionality of the sensor ROS node with tests this leads to the following problems:

  • You would have to prepare (setup) the sensor and other parts of the ROS system before the execution of a test. This would make an automated test execution in a local or CI build environment hard or impossible. As consequence you would not be able to verify the ROS sensor nodes functionality in a ROS unit test or ROS node integration test setup.
  • You would not be able to configure any of the sensor's environmental conditions which could be required to be verified. This is usually the case for environmental conditions which occur in the field never or rarely but need to be detected and handled as error cases. As consequence you could miss the verification of critical node functionality completely.

You want to execute tests in local builds or CI builds only without depending on the sensor hardware. This means you have to break the dependency of the ROS node on the actual hardware during tests.

A solution to this problem is to use dependency injection on the ROS node level. The dependency of the ROS node on one class or several classes which abstract hardware are injected into the ROS node. A suitable implementation is to define one or several node ROS parameters which indicate wether production or test variants of the classes are used. The production variants of the classes implement the actual hardware dependent functionality. The test variants of the classes do not depend on hardware and allow the configuration of the class interface's output data (e.g. member functions return values). Complex logic can require to implement several test variants for a single class for different scenarios.

The image below shows the (probably) simplest case: The ROS node functionality is implemented with a single class which just provides the sensor data.

Image

Break the dependency on real actuators

TODO - explain the example

Image

results matching ""

    No results matching ""