For my next embedded systems project I want to embrace unit testing. It may not technically be test driven development, but I would at least like to instrument unit tests up front and have comprehensive unit testing.
I am using the IAR EWARM tool chain. I am considering using cmocka, unity, or cunit. I am learning towards using µC/OS-III as the RTOS.
Here's the question: How is unit testing going to work with an RTOS in the picture? E.G: Should I disable the kernel and unit test the code as a single threaded application and stub all/most kernel calls, or is there a better way?
Example: In µC/OS-III the entry point is still main. From main you call any init code and then make a call to OSStart() to begin multitasking. So when I am running the test harness I could just not make the call to OSStart()
#ifdef UNIT_TEST
test_runner();
#else
OSStart(&err);
#endif
Then in all of my application code in the tasks I would just need to mock message passing and delay calls to the kernel.
Is that the best way to do this. Or would I be better suited starting the kernel, creating a task for my test runner, and running all of the tasks from that as a single thread, or is there some other good approach involving spawning the other tasks from the test harness.
You seem to have a misconception about unit testing. Whether your code uses an RTOS is not relevant because unit testing involves testing the code modules, i.e., C functions, in isolation. The RTOS would not be operating during your test.
Unit Testing also presumes you are testing against a set of requirements that define the functionality of the code. The goal of most unit testing is to be able to provide various forms of coverage of your code. This includes statement, decision and multiple condition decision coverage.
Statement coverage shows that you have exercised every line of code in the function.
Decision coverage involves showing that both sides (true/false) of all conditions are covered.
Multiple condition decision coverage (MCDC) is used to test complex decisions, i.e., if (a && (b || c)) and insure that all variations are covered. MCDC testing is usually limited to very critical applications such as avionics where failure can have catastrophic results.
Subroutines are typically stubbed, i.e., intercepted and controlled, to prove that each was called in order and that passed arguments are correct and various returned values function correctly.
I admit I don't have any experience with the tools you mention but there are a number of commercial unit test tools available, Cantata, LDRA TestBench, IBM Rational Test Real Time and others that are suitable for in depth unit testing.
There are also commercial solutions for the RTOS itself. My company offers and off-the-shelf unit and integration test package for both µC/OS-II and µC/OS-III.
Scott Validated Software