Testing Trophy

Figure 1: The testing trophy according to Test Pyramid 

From theory to practice: unit testing for embedded software

Unit testing is a well-understood concept; corresponding frameworks and extensive technical literature exist for every programming language. It is one of the standard quality assurance measures used in modern development projects. Unit testing has an undeniably positive impact on code quality and reduces the risk of errors, for example through regression testing. Of course, other test methods are also necessary in a project, such as static code analysis along with integration and system tests. The testing trophy (see Figure 1) shows that each individual test method has its place and that the associated work has to be scaled accordingly. Going back to unit tests: these are relatively quick to set up, ideally in conjunction with code development because the scope is small (the unit). If the test is designed well, then dependencies can be effectively substituted with mocks.

However, when it comes to embedded development projects we often find that unit testing is implemented only sporadically or not at all. Why might this be? Here are a few possible reasons and how we at CSA respond to them:

 

There are so many unit test frameworks. Which is the best?

We have had very good experiences with Google Test and Google Mock. These frameworks offer powerful functions, are extremely well-documented and widely distributed, and continue to be refined on an ongoing basis.

 

Unit testing on the target is slow and laborious

Yes, that’s true. But we believe that the majority of the application code should be tested on the development PC, in other words with Windows or Linux. Programs are quick to execute in this environment, debugging is straightforward, and additional features such as code coverage are available. It’s also easy to automate processes using CI tools.

 

The code has too many dependencies and cannot be tested

Is it possible that architecture and design have been neglected, and the code has become bloated? Modern microcontrollers usually have a large flash memory. The use of interfaces and methods such as dependency injection improves testability, as well as helping to create a clearer design and more portable code. We use our building block framework for this purpose, in which these aspects have already been taken into consideration.

 

It’s difficult to test hardware-oriented code in a unit test

That’s correct. Unit tests are rarely the best choice for hardware-oriented code. The right tool and the right test method need to be used for every task. We have been able to test HAL libraries successfully and effectively with integration tests.

Mock und Unit Test

Figure 2: A mock and a unit test (see gmock for dummies)

How do I use Google Test and Google Mock to test a C project?

The C headers also need to be able to be integrated into the C++ test code. Additional glue codes are also needed for the mock test, but it can then be used as normal. We have already used this approach to successfully test SIL 4 projects for railway applications.

 

The compiler does not support my unit testing library

It doesn’t need to. A good design encapsulates hardware-specific and compiler-specific code. Thanks to the use of C and C++, most of the code is portable and can be tested on the development PC with a suitable compiler. We have always had very good outcomes using this approach.

 

The project doesn’t contain any unit tests – why should any be written now?

If the newly developed code has unit tests, then that’s a good first step. We have successfully integrated unit testing into existing projects and have managed to gradually increase the test coverage.

 

The unit testing framework is not integrated in the project

The process for integrating a unit test framework is well documented and easy to apply. So this excuse isn’t valid. Our embedded toolchain has enabled us to seamlessly integrate all the necessary tools. This means that writing a unit test is almost easier than having executable code on the target system.

Here at CSA engineering, we have broad technical knowledge of unit testing and successfully use this type of test in embedded projects.

We would also be happy to advise you on your projects and provide training if required.

Do not hesitate to get in touch!

Contact us