Hi,
I want to unit test my application code, which in turn uses ChibiOS HAL (as well as the OS itself, but let's focus on HAL now). I'm using CMock and Unity. With CMock, I can provide a header, and CMock will automatically create mock implementations based on any function prototype it finds in the header. I build with GCC and run the unit tests on my host PC. The setup works really well for mocking other modules, but I run into several problems when trying provide the hal headers to CMock. I've managed to solve a couple of them, but wanted input from others before I jump too far down a rabbit hole.
The main issue I'm facing now is either macros or static inline functions that write directly to some memory address, causing segfaults when running on my PC. For example the macro palClearLine(). What I'd ideally need is function prototypes instead of macros, so that CMock can mock them. I've solved some other issues, and I wouldn't be surprised if I'd run into more if I kept going.
My ideas on how to continue:
* Create my own version of hal.h, where I minimally put in whatever I want, and use it for unit testing only (manual work, hard for other developers to expand, risk of making bad mistakes)
* Preprocess hal.h, and edit it to my liking (similar to the above)
* Create a simple abstraction layer between my application code and HAL, and skip HAL in my unit tests (abstraction layer of abstraction layer?)
* Edit hal.h, so that test builds come out with a different content
These all have ups and downsides, and I don't really love any of them
My question is, if someone has done something similar (mocking the HAL completely for off-target unit tests). Any input would be appreciated!
Cheers
Albin
Mocking of HAL for unit test purposes
- Giovanni
- Site Admin
- Posts: 14458
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Mocking of HAL for unit test purposes
Hi,
No experience with cmock, the OS includes its own unit test engine. It looks like a lot of work reworking all headers.
Giovanni
No experience with cmock, the OS includes its own unit test engine. It looks like a lot of work reworking all headers.
Giovanni
- Giovanni
- Site Admin
- Posts: 14458
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Mocking of HAL for unit test purposes
Any news? not sure how I could help there
Would you be interested in learning how the ChibiOS unit test engine works? it is pretty unique in its own way.
Giovanni
Would you be interested in learning how the ChibiOS unit test engine works? it is pretty unique in its own way.
Giovanni
Re: Mocking of HAL for unit test purposes
Hi Giovanni,
Sorry for my slow reply, I was on vacation for the last couple of weeks.
I think you are correct that reworking the headers like that would be a lot of work. For now I think we will just go with creating our own fake hal.h for unit test builds, which includes necessary function prototypes. I think this is akin to manually specifying your mocks (as is common for other frameworks, for example Gmock or as describe here using Fake Function Framework: https://deadlock-reader-sw.readthedocs. ... sting.html). We would get the automatic generation of the mock implementations, and for other application code, the mock prototypes will still be automatically identified and generated as well (which is my main reason for using CMock and Unity).
A small introduction to the ChibiOS unit test engine would be interesting, is there an explanation somewhere?
Best regards
Albin
Sorry for my slow reply, I was on vacation for the last couple of weeks.
I think you are correct that reworking the headers like that would be a lot of work. For now I think we will just go with creating our own fake hal.h for unit test builds, which includes necessary function prototypes. I think this is akin to manually specifying your mocks (as is common for other frameworks, for example Gmock or as describe here using Fake Function Framework: https://deadlock-reader-sw.readthedocs. ... sting.html). We would get the automatic generation of the mock implementations, and for other application code, the mock prototypes will still be automatically identified and generated as well (which is my main reason for using CMock and Unity).
A small introduction to the ChibiOS unit test engine would be interesting, is there an explanation somewhere?
Best regards
Albin
- Giovanni
- Site Admin
- Posts: 14458
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Mocking of HAL for unit test purposes
Hi,
No documentation yet, it is about generating test suites starting on an XML description, source code is generated. It produces those reports available in ChibiOS.
I could organize a live session on Discord if there is interest.
Giovanni
No documentation yet, it is about generating test suites starting on an XML description, source code is generated. It produces those reports available in ChibiOS.
I could organize a live session on Discord if there is interest.
Giovanni
Re: Mocking of HAL for unit test purposes
Giovanni wrote:Hi,
No documentation yet, it is about generating test suites starting on an XML description, source code is generated. It produces those reports available in ChibiOS.
I could organize a live session on Discord if there is interest.
Giovanni
Is that the one where the test cases (code) are in the actual XML?
- Giovanni
- Site Admin
- Posts: 14458
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Mocking of HAL for unit test purposes
faisal wrote:Is that the one where the test cases (code) are in the actual XML?
Not whole test cases but yes, that one.
Giovanni
Re: Mocking of HAL for unit test purposes
Hey,
In case someone is interested, here's the approach I went with, that so far works very well in my setup.
So, the goal is to have hal/ch headers that:
I built an automatic pre-processor script for the purpose, that is run on each relevant hal/ch header:
What remains is missing macros. For these I created a separate header, that get's prepended to my new hal.h. The content of this file is:
I was afraid that this custom header file would grow big, but after some 20 additions, I managed to get several source files and tests to build just fine.
These modified headers are only used for unit testing with Unity and CMock
In case someone is interested, here's the approach I went with, that so far works very well in my setup.
So, the goal is to have hal/ch headers that:
- Don't have macros (or, at least not macros that have side effects)
- Have function prototypes, but not inline functions
- Are individually independent of include order (this is needed for CMock)
I built an automatic pre-processor script for the purpose, that is run on each relevant hal/ch header:
- Remove all macros
- Re-write inline functions to normal prototypes
- Adds #include "hal.h" to the top of each header (so that all types, etc, are available when CMock reads the header)
What remains is missing macros. For these I created a separate header, that get's prepended to my new hal.h. The content of this file is:
- Macros that are purely necessary for compilation, such as STM32_DMA_IS_VALID_ID(..). These I just chose so that my code compiles
- Some helper macros, that I left intact (such as TIME_MS2I(..))
- Function prototypes, that I wrote to replace macros, such as palSetLine(..) into "void palSetLine(uint32_t line);"
I was afraid that this custom header file would grow big, but after some 20 additions, I managed to get several source files and tests to build just fine.
These modified headers are only used for unit testing with Unity and CMock
Return to “Development and Feedback”
Who is online
Users browsing this forum: No registered users and 12 guests