You have shown yourself what happens if you don’t make the code unit testable, by including files of the framework that are not available for desktop. When your to-be-tested business logic unit is compiled during the unit tests and it requires, through the include chain, a #include "stm32_hal.h"
and friends and that file isn’t there, compilation will fail and there’s no way around that if the file does not physically exist. That’s why we have many techniques in software design that battles this (Writing Testable Code. Many developers have a hate… | by Pedro Câmara | Feedzai Techblog | Medium).
But one can also attack this problem the other way around, as you’ve already noted
There are libraries / testing frameworks where you can mock functions. Then your business logic can still include all the microcontroller framework related stuff because those includes are now actually provided by a special testing library that is controllable in a way that you can make a certain function return what you want in the course of a specific unit test, to test how the business logic reacts to it.
PlatformIO has readily-available examples to test that out: platformio-examples/unit-testing/arduino-mock at develop · platformio/platformio-examples · GitHub. It uses the ArduinoFake library and during a unit test, one can e.g. do
So here we setup the Arduino mock library in such a way that when the business-logic calls digitalWrite()
and digitalRead()
, we control exactly what is returned and can also verify that a function was then called a certain number of times or with specific arguments for verification. The unit tests and the business logic still have #include <Arduino.h>
in them because the ArduinoFake library provides that header and all the normal Arduino types and APIs, they are just all being redirected into controllable mock functions. The business logic doesn’t know it’s being mocked under-the-hood.
However, I’ve only ever seen such a mocking framework for Arduino with ArduinoFake, not for the STM32 HAL. And given that the STM32HAL is rather huge with many modules and functions, compared to the Arduino core, it would take some effort to write the mocking framework for it. Maybe other frameworks like google-test / gmock are more general in that regard, but I have no experience with those libraries. But people have definitely got it running with PlatformIO and native desktop. Maybe GMock is what you’re looking for, but I can’t confirm it.
Of course, one can also chose to run the embedded tests on the embedded device itself. PlatformIO has a readily-available example for that located at platformio-examples/unit-testing/stm32cube at develop · platformio/platformio-examples · GitHub specifically for the STM32Cube case. There, the entire HAL is available and compiled as normal, and can thus be used during the unit tests. But that will then also trigger something in hardware, like writing to a pin, instead of being mocked and internally not happening anything.