You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I use unit testing by using CMake and Unity, and have it integrated into the CI workflow for my work projects.
I would like to be able to use Ceedling to create the mocks and test runners, but ...
It's very slow - a CI build of the source on my project takes 3 minutes, while Ceedling takes around 20 minutes - they need to be equivalent times
Ceedling is difficult to configure - I don't want to learn Ruby - I want to use it as a tool
Ceedling fails for functions called via a macro - eg an API layer function calling a temperature sensor which can be implemented in a number of different sensor modules. Calling via a function macro is clean at the API layer, and a config H file defines the macro to be the driver layer function, and includes the driver layer H file, allowing a build to use the temperature sensor used on the PCB for that build
Ceedling fails if a function is declared in an H file but not implemented
I would suggest:
to add an option to allow Ceedling to run, generate the mocks and test runners only if any H file has changed, then generate CMake files, and exit. The CI could then build and run the tests faster by just running the CMake files, in the very usual case where H files had not changed.
convert Ceedling to use YML files for configuration.
a roadmap to indicate what changes are in the pipeline - to allow me to evaluate whether or not to switch to FFF
You can generate mocks and runners directly - using CMock's scripts. You do not need Ceedling for that. What Ceedling is great, is generating header files for that exact test file (so making "presonalized dependencies").
Not sure why API layer function like macros are something you would even want to unit test. You want to unit test sensor's main functions. You need to know which sensor has what expects/returns, so this is certainly not the part you would want to generalize. Do you maybe want to just mock API layer? Then create a fake proper function header file, which Ceedling will easily mock for tests. Or wrap around your function like macro magic with `#ifndef TEST #define .... #else void proper_function #endif and it should also work just fine.
Ceedling already generates full YML file for you and guides you through the process. Can you specify what should be improved/missing from https://throwtheswitch.github.io/Ceedling/latest/getting-started/installation/#getting-started-after-installation ? You wrote it is hard to configure, but it seems really easy with the dedicated commands like new, module:create and other commands. This is something that makes Ceedling way more easier than any CMake or even Makefile alternative - as long as you do not want to extend outside of the Ceedling's scope (and even then you have options). You could use for example Ceedling to build and run tests, while building release binary is done via CMake/Makefile or whatever else. I am not saying Ceedling does not do good job at building a release, but some people want some special stuff to happen for the release - and that might be difficult to inject by Ceedling.
Roadmap is something in head of maintainer and shared with us based on the issues, but since project is open-source you are free to open a feature request and contribute to it. Or pay someone to contribute, since you do not want to learn Ruby. It is a lot of effort to create a Roadmap (and maintain it), especially since there is just a small team which has no use of such overview - or even time to perform prioritysation. Mark does regularly merge the Pull requests, so there is that option.
Thank you for your speedy and comprehensive answer.
I have not explained the issue with macros well:
If I write a module api_temp.c that #includes api_temp_cfg.h
and in the api_temp.c write a function which calls API_TEMP_STATUS_GET(),
and in api_temp_cfg.h write
#ifdef PCB_IS_V2
#include drv_tmp144.h
#define API_TEMP_STATUS_GET() DRV_Tmp144_Status_Get()
#endif
#ifdef PCB_IS_V3
#include drv_sht30.h
#define API_TEMP_STATUS_GET() DRV_Sht30_Status_Get()
#endif
etc
For the unit test of api_temp, I would mock drv_tmp144 and drv_sht30 for different PCBs. For example, if I create a Ceedling project for V2 PCB. However, Ceedling/CMock has issues with API_TEMP_STATUS_GET. It seems to see API_TEMP_STATUS_GET as a macro and then not mock drv_tmp144.c functions.
I will try your suggestion of using just CMock rather than Ceedling to generate the mocks and runners. I think that would just leave the CMake files to be generated semi-manually.
So what prevents you to have that same cfg macro decision inside the utest file and then mock directly those files? You want to run those tests twice anyway it seems (I assume you looked at partials). We are diverging from the roadmap topic, so maybe open a new issue with nice codeblocked example so that we can give you advice quicker. As for roadmap, I assume maintainer has similar opinion, as I am not a member of the maintaining team :)
@dermot-murphy Thank you for submitting all this. There's quite a lot to respond to.
There is work we will be doing to speed up build times. A casualty of the massive amount of work that went into the 1.0.0 release removed delta builds (only building what has changed). This will return again. That said, Ceedling can only be so fast. The feature set and limitations of the C language require quite a bit of text scanning, preprocessing, and file generation.
I am quite confused about your request to configure Ceedling with YAML. In fact, a Ceedling configuration file is YAML already. That is Ceedling’s claim to fame—one (often short) YAML file to configure a test and/or release build. Only if you are intending to implement advanced features or customizations do you need to touch Ruby.
Generating CMake files might perhaps appear in the future. You are not the first to suggest this. That said, it's a huge undertaking and not presently envisioned to be core to Ceedling.
You do not need to evaluate FFF vs. Ceedling. Ceedling already supports FFF. If you would like to use Ceedling and FFF, you may do so today. An FFF plugin exists that entirely replaces CMock to generate and use fakes instead of mocks.
Yes, a test executable build will fail if a function is not defined. If that function is called, it must have a definition. There's multiple ways to manage this. You have a couple mechanisms to pull in the source definitions or you can trigger a mock of that function declaration (see documentation links below).
I'll need to digest the macro issue you discussed. I'm quite sure your need is testable with Ceedling.
Your request to generate only mocks and/or test runners has come up before. I think we're in a good spot to implement this. I will try to squeeze it into the upcoming 1.1.0 release.
As for a roadmap, we would love to be able to produce such a thing. Please understand that today Ceedling is almost entirely volunteer contributions. A proper roadmap, a variety of features, proper support, etc. are simply out of reach. That said, we are working towards building a business around Ceedling and generating income to properly sponsor such efforts. We are early on in this effort. Ceedling Assist engagements have begun to sponsor work. A large European company sponsored the headlining feature, Partials, for the upcoming 1.1.0 release. If you or your company are in such a position, please also consider becoming a Github Sponsor for Ceedling.
I will get back to you on some of these items. In the meantime, I will point you to the (not quite finished) new documentation site for Ceedling. Styling and layout are in a bit of flux right now. It begins with version 1.1.0 which is not released yet, but some of the issues you have raised are addressed quite comprehensively in the documentation.
Please feel free to offer feedback on the new documentation site that supersedes the previous monolithic user manual. You probably represent exactly the sort of user of the documentation we want to support.
Your questions about Ceedling as a tool and using YAML input inspired us to make clearer what Ceedling is and how it works. We added simple explanations and simple YAML configuration / command line examples at all of the most important documentation entry points to ensure understanding of Ceedling as a tool and not a Ruby library. I am very curious to know how you were running Ceedling if not as ceedling ... at the command line—if you'd care to share.
We were not able to squeeze in only runner and mock generation in the big 1.1.0 release of a few days ago, but the rigging is now all there to support this in 1.2.0.
There's really not a whole lot we can do to achieve the build speeds you are interested in. Optimizations are certainly forthcoming and multi-threaded builds help. But, the essential tradeoff for Ceedling is developer ease versus build speed. You are always welcome to hand create Unity test runners, run CMock directly, and rig up CMake, Makefiles, or other build solutions yourself. In part, the complementary frameworks of Unity and CMock exist separately for this use case. This sort of hand-rolled build will run much faster than Ceedling. The tradeoff is the hand-editing, organizing the build rigging, and remembering to update files. That's what Ceedling is here for—simple builds with automated discovery / file generation and no forgetting to update certain files (e.g. adding test case functions but not adding them to a Unity runner).
As for the macros and ifdefs in your original question, it's hard to comment properly without knowing your project layout and specific testing goals. So, I'll only speak to your need in general terms:
Ceedling / CMock / Unity are capable of dealing with even complex conditional compilation and macros. But, this generally requires one or both of the following: enabling test preprocessing and defining symbols for test compilation. When these are active then the final form of your C source is expanded and function declarations or selectively enabled code can be discovered and parsed as the input to generating mocks or in the build process for a test case function to execute.
I doubt you want to take this approach, but it is also possible to test up to calling macros themselves and not testing their expanded code. In this case, with some appropriate arranging of test support files and build search paths you can mock a function declaration that is semantically identical to the macro. If the macro is not pulled in to the test suite build—using project organization—the C call to the macro in source becomes an indistinguishable function call that can be tested against. This technique is usually reserved for advanced cases where complex macros are in use. In such cases it can become valuable to both test up to calls of those macros and then separately test the macro expansions. Again, I doubt this is your use case.
Unfortunately, until we succeed in garnering greater sponsorship and build up a business around these tools, things like entirely valuable roadmaps remain out of reach. These tools have built up a sizable following. NASA used these tools to support development for multiple Mars missions! With greater popularity comes a greater need for support, bug fixes, development, work on safety certification, etc. With only volunteer contributions, we just cannot make all the things happen that could and should happen. Hopefully this will change as those that have come to rely on these tools contribute to sponsorship and spend money on commercial products (the first on the horizon). If you have ideas on how to make it through this difficult transition into fully mature and resourced tools, we are all ears.
Hi,
Thank you for the detailed response.
I misunderstood the yml file that Ceedling used, as I only use yml on github actions, so am not so good at recognising it - I assumed it was something ruby like from the discussion of Ruby in the docs. My bad.
Currently, we hand write cmake files, test programs (using unity), as well as the mocks. The tests are then run using ctest or by running the test executable. We wanted to swap to a more automated approach, which Ceedling offers, replacing manual cmake and mock writing.
The main issues we have had are:
Getting Ceedling to create mocks and build without errors. The learning curve seems much more than expected, but perhaps we need to adjust how we write our application configuration files. We do this kind of thing:
In the c file:
#include temperature_cfg.h
int16_t TemperatureGet(void)
{
return TEMPERATURE_SENSOR_READ() ;
}
In the cfg file:
#ifdef FEATURE_SENSOR_TMP144
#include tmp144.h
#define TEMPERATURE_SENSOR_READ TMP144_READ
#endif
#ifdef FEATURE_SENSOR_SHT
#include sht.h
#define TEMPERATURE_SENSOR_READ SHT_READ
#endif
It is more complicated than this, but the issue was Ceedling not recognising that a mock file and function were needed, even when FEATURE_SENSOR_SHT is defined.
We are experimenting with generating the tests using Claude from Doxygen comments for each file and function, where the comments say what the file and functions should do.
Once configured correctly, Ceedling seems to take a long time to run. Our budget for on-push testing is 5 minutes. This is burned up just rescanning the files, and regenerating the mocks. We haven't spent enough time to setup Ceedling on github actions, so that it would only scan and regenerate those files which need to be changed, based on the files changed in the commit. Currently, we have tried updating the files in precommit, or asking engineers to run Ceedling first, then committing and pushing. Neither is satisfactory, and Ceedling is really only run after a build on push fails, or on a pr. Everything else: build, style, coding standard, static analysis, doxygen warning check, and smoke test on target are run on push. It is the logical spot for Ceedling to fit into, but we can only run manually written files for unit testing here. Checking/regeneration of mocks, the scanning of includes to create the cmake files, takes too long. I feel if we are able to do a static analysis here on the time budget, we should be able to have Ceedling run in this time - regenerate mocks, test runners and test cmake files, but this may be my over expectation.
We have played around, but not closed out, using the unit and integration tests currently running on host, to also run on target and report over uart. This is needed for part of ISO26262. It would be good to have a suite and test runner, with overall application to run, as part of the framework. We would be happy to donate this on completion.
The more tools in the system, the more admin it takes for ASPICE. We use C and Python for lots of other tools, but the dependency on Ruby is only via Ceedling.
Ceedling certainly has the potential to be developed into a much wider test ecosystem, automated, driven from jira tickets, running on host and on target, and exporting to project status boards and exporting into test management tools. All out of the box, which should perhaps be, one of the most important goals.
I will come back to Ceedling in the next few weeks, and will try out the new version.
Keep up the good work, as it is much appreciated.
Many thanks
Dermot
Sent from Outlook for Android<https://aka.ms/AAb9ysg>
________________________________
From: Michael Karlesky, PhD ***@***.***>
Sent: Saturday, 18 July 2026 19:41:04
To: ThrowTheSwitch/Ceedling ***@***.***>
Cc: Dermot Murphy ***@***.***>; Mention ***@***.***>
Subject: Re: [ThrowTheSwitch/Ceedling] Ceedling road map (Issue #1154)
[https://avatars.githubusercontent.com/u/1048550?s=20&v=4]mkarlesky left a comment (ThrowTheSwitch/Ceedling#1154)<#1154 (comment)>
@dermot-murphy<https://github.com/dermot-murphy> So sorry for the slow follow up…
Your questions about Ceedling as a tool and using YAML input inspired us to make clearer what Ceedling is and how it works. We added simple explanations and simple YAML configuration / command line examples at all of the most important documentation entry points to ensure understanding of Ceedling as a tool and not a Ruby library. I am very curious to know how you were running Ceedling if not as ceedling ... at the command line—if you'd care to share.
We were not able to squeeze in only runner and mock generation in the big 1.1.0 release of a few days ago, but the rigging is now all there to support this in 1.2.0.
There's really not a whole lot we can do to achieve the build speeds you are interested in. Optimizations are certainly forthcoming and multi-threaded builds help. But, the essential tradeoff for Ceedling is developer ease versus build speed. You are always welcome to hand create Unity test runners, run CMock directly, and rig up CMake, Makefiles, or other build solutions yourself. In part, the complementary frameworks of Unity and CMock exist separately for this use case. This sort of hand-rolled build will run much faster than Ceedling. The tradeoff is the hand-editing, organizing the build rigging, and remembering to update files. That's what Ceedling is here for—simple builds with automated discovery / file generation and no forgetting to update certain files (e.g. adding test case functions but not adding them to a Unity runner).
As for the macros and ifdefs in your original question, it's hard to comment properly without knowing your project layout and specific testing goals. So, I'll only speak to your need in general terms:
* Ceedling / CMock / Unity are capable of dealing with even complex conditional compilation and macros. But, this generally requires one or both of the following: enabling test preprocessing<https://throwtheswitch.github.io/Ceedling/latest/testing-guide/conventions/#test-file-preprocessing> and defining symbols for test compilation<https://throwtheswitch.github.io/Ceedling/latest/configuration/reference/defines/>. When these are active then the final form of your C source is expanded and function declarations or selectively enabled code can be discovered and parsed as the input to generating mocks or in the build process for a test case function to execute.
* I doubt you want to take this approach, but it is also possible to test up to calling macros themselves and not testing their expanded code. In this case, with some appropriate arranging of test support files and build search paths you can mock a function declaration that is semantically identical to the macro. If the macro is not pulled in to the test suite build—using project organization—the C call to the macro in source becomes an indistinguishable function call that can be tested against. This technique is usually reserved for advanced cases where complex macros are in use. In such cases it can become valuable to both test up to calls of those macros and then separately test the macro expansions. Again, I doubt this is your use case.
Unfortunately, until we succeed in garnering greater sponsorship and build up a business around these tools, things like entirely valuable roadmaps remain out of reach. These tools have built up a sizable following. NASA used these tools to support development for multiple Mars missions! With greater popularity comes a greater need for support, bug fixes, development, work on safety certification, etc. With only volunteer contributions, we just cannot make all the things happen that could and should happen. Hopefully this will change as those that have come to rely on these tools contribute to sponsorship and spend money on commercial products (the first on the horizon). If you have ideas on how to make it through this difficult transition into fully mature and resourced tools, we are all ears.
—
Reply to this email directly, view it on GitHub<#1154?email_source=notifications&email_token=AQENAD57A2M6XDXSY7A4NH35FPAD5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMBRGI2DMMRSGI3KM4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5012462226>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AQENAD2H3IBHRK73JWSQ42L5FPAD5AVCNFSNUABDKJSXA33TNF2G64TZHMZTENZWHA3TOO2JONZXKZJ3GQ2TGMJUGM4TKOBUUF3AE>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
Activity
Letme commentedon May 27, 2026
You can generate mocks and runners directly - using CMock's scripts. You do not need Ceedling for that. What Ceedling is great, is generating header files for that exact test file (so making "presonalized dependencies").
Not sure why API layer function like macros are something you would even want to unit test. You want to unit test sensor's main functions. You need to know which sensor has what expects/returns, so this is certainly not the part you would want to generalize. Do you maybe want to just mock API layer? Then create a fake proper function header file, which Ceedling will easily mock for tests. Or wrap around your function like macro magic with `#ifndef TEST #define .... #else void proper_function #endif and it should also work just fine.
Ceedling already generates full YML file for you and guides you through the process. Can you specify what should be improved/missing from https://throwtheswitch.github.io/Ceedling/latest/getting-started/installation/#getting-started-after-installation ? You wrote it is hard to configure, but it seems really easy with the dedicated commands like
new,module:createand other commands. This is something that makes Ceedling way more easier than any CMake or even Makefile alternative - as long as you do not want to extend outside of the Ceedling's scope (and even then you have options). You could use for example Ceedling to build and run tests, while building release binary is done via CMake/Makefile or whatever else. I am not saying Ceedling does not do good job at building a release, but some people want some special stuff to happen for the release - and that might be difficult to inject by Ceedling.Roadmap is something in head of maintainer and shared with us based on the issues, but since project is open-source you are free to open a feature request and contribute to it. Or pay someone to contribute, since you do not want to learn Ruby. It is a lot of effort to create a Roadmap (and maintain it), especially since there is just a small team which has no use of such overview - or even time to perform prioritysation. Mark does regularly merge the Pull requests, so there is that option.
dermot-murphy commentedon May 27, 2026
Thank you for your speedy and comprehensive answer.
I have not explained the issue with macros well:
If I write a module api_temp.c that #includes api_temp_cfg.h
and in the api_temp.c write a function which calls API_TEMP_STATUS_GET(),
and in api_temp_cfg.h write
#ifdef PCB_IS_V2
#include drv_tmp144.h
#define API_TEMP_STATUS_GET() DRV_Tmp144_Status_Get()
#endif
#ifdef PCB_IS_V3
#include drv_sht30.h
#define API_TEMP_STATUS_GET() DRV_Sht30_Status_Get()
#endif
etc
For the unit test of api_temp, I would mock drv_tmp144 and drv_sht30 for different PCBs. For example, if I create a Ceedling project for V2 PCB. However, Ceedling/CMock has issues with API_TEMP_STATUS_GET. It seems to see API_TEMP_STATUS_GET as a macro and then not mock drv_tmp144.c functions.
I will try your suggestion of using just CMock rather than Ceedling to generate the mocks and runners. I think that would just leave the CMake files to be generated semi-manually.
Letme commentedon May 27, 2026
So what prevents you to have that same cfg macro decision inside the utest file and then mock directly those files? You want to run those tests twice anyway it seems (I assume you looked at partials). We are diverging from the roadmap topic, so maybe open a new issue with nice codeblocked example so that we can give you advice quicker. As for roadmap, I assume maintainer has similar opinion, as I am not a member of the maintaining team :)
mkarlesky commentedon May 27, 2026
@dermot-murphy Thank you for submitting all this. There's quite a lot to respond to.
As for a roadmap, we would love to be able to produce such a thing. Please understand that today Ceedling is almost entirely volunteer contributions. A proper roadmap, a variety of features, proper support, etc. are simply out of reach. That said, we are working towards building a business around Ceedling and generating income to properly sponsor such efforts. We are early on in this effort. Ceedling Assist engagements have begun to sponsor work. A large European company sponsored the headlining feature, Partials, for the upcoming 1.1.0 release. If you or your company are in such a position, please also consider becoming a Github Sponsor for Ceedling.
I will get back to you on some of these items. In the meantime, I will point you to the (not quite finished) new documentation site for Ceedling. Styling and layout are in a bit of flux right now. It begins with version 1.1.0 which is not released yet, but some of the issues you have raised are addressed quite comprehensively in the documentation.
Please feel free to offer feedback on the new documentation site that supersedes the previous monolithic user manual. You probably represent exactly the sort of user of the documentation we want to support.
mkarlesky commentedon Jul 18, 2026
@dermot-murphy So sorry for the slow follow up…
Your questions about Ceedling as a tool and using YAML input inspired us to make clearer what Ceedling is and how it works. We added simple explanations and simple YAML configuration / command line examples at all of the most important documentation entry points to ensure understanding of Ceedling as a tool and not a Ruby library. I am very curious to know how you were running Ceedling if not as
ceedling ...at the command line—if you'd care to share.We were not able to squeeze in only runner and mock generation in the big 1.1.0 release of a few days ago, but the rigging is now all there to support this in 1.2.0.
There's really not a whole lot we can do to achieve the build speeds you are interested in. Optimizations are certainly forthcoming and multi-threaded builds help. But, the essential tradeoff for Ceedling is developer ease versus build speed. You are always welcome to hand create Unity test runners, run CMock directly, and rig up CMake, Makefiles, or other build solutions yourself. In part, the complementary frameworks of Unity and CMock exist separately for this use case. This sort of hand-rolled build will run much faster than Ceedling. The tradeoff is the hand-editing, organizing the build rigging, and remembering to update files. That's what Ceedling is here for—simple builds with automated discovery / file generation and no forgetting to update certain files (e.g. adding test case functions but not adding them to a Unity runner).
As for the macros and
ifdefs in your original question, it's hard to comment properly without knowing your project layout and specific testing goals. So, I'll only speak to your need in general terms:Unfortunately, until we succeed in garnering greater sponsorship and build up a business around these tools, things like entirely valuable roadmaps remain out of reach. These tools have built up a sizable following. NASA used these tools to support development for multiple Mars missions! With greater popularity comes a greater need for support, bug fixes, development, work on safety certification, etc. With only volunteer contributions, we just cannot make all the things happen that could and should happen. Hopefully this will change as those that have come to rely on these tools contribute to sponsorship and spend money on commercial products (the first on the horizon). If you have ideas on how to make it through this difficult transition into fully mature and resourced tools, we are all ears.
dermot-murphy commentedon Jul 19, 2026