Unit Testing Firmware



  • I am big fan of unit testing, I have some experience with it with Java. My proposal is to start unit testing the Duet firmware also. But for C++ there are different testing frameworks. I found so far: Catch 2, Google Test and RapidCheck. Is it possible to agree on one of those frameworks?
    I want to start testing the Scara kinematics, but want to test all the drive and movement planning methods to understand them (e.g. validating movement - speed - time dependencies).


  • administrators

    Unit testing firmware is more challenging than unit testing desktop software.

    Let's start with the easier part: unit testing modules that don't access the hardware. To run unit tests for those modules on a PC, you either need to know that the implementation-defined parts of the C and C++ languages that are used by the firmware are implemented in exactly the same way by the compilers for your PC and for your embedded platform, or (preferably) have an emulator running in the PC that reads the embedded firmware binary and simulates executing it on the appropriate ARM processor - see for example https://www.thefreecountry.com/emulators/arm.shtml (disclaimer: I haven't used any of those).

    To run unit tests on those firmware modules that access hardware, you also need to emulate the hardware peripherals concerned, and the stepper motors, thermistors etc. connected to the hardware.

    RepRapFirmware provides a small number of features akin to unit tests, for example direct motor movement (G1 S2 commands) and various subfunctions of M122.



  • the implementation-defined parts of the C and C++ languages that are used by the firmware are implemented in exactly the same way by the compilers for your PC

    Typically there are large chunks of logic that are not compiler or architecture specific that can easily unit tested. An example from the PanelDue src/Hardware/Serialio.cpp, the function CheckInput is a finite state machine that parses a json stream and calls event handling functions. Same the ConvertUnicode method before it, both can easily being decoupled from the hardware.

    https://github.com/dc42/PanelDue/blob/master/src/Hardware/SerialIo.cpp#L287

    Not criticizing the code, just commenting on the concept of design for testability, though I am sure you can teach me a thing or two about software reliability 😉 https://www.eschertech.com/company/index.php



  • Thank you for the valid points to be considered. I will start at some high level methods, which are not near the hardware. The hardware must be encapsulated into mock objects then.

    If the unit tests are successful and useful, you may decide whether it's worth using at a broader level.

    Maybe someone has a hint what I should use as framework. From reading the descriptions, I will try RapidCheck. It creates the test cases automatically.


Log in to reply