Unit Testing Embedded Software [closed]
What best practices have you used in unit testing embedded software that are peculiar to embedded systems?
Solution 1:
Embedded software may have come a long way in the last 10 years but we generally did the following:
- for algorithms that didn't depend on the target hardware, we simply had unit tests that were built and tested on a non-embedded platform.
- for stuff that did require the hardware, unit tests were conditionally compiled into the code to use whatever hardware was available. In our case, it was a serial port on the target pushing the results to another, more capable, machine where the tests were checked for correctness.
- Depending on the hardware, you could sometimes dummy up a "virtual" device on a non-embedded platform. This usually consisted of having another thread of execution (or signal function) changing memory used by the program. Useful for memory mapped I/O but not IRQs and such.
- typically, you could only unit test a small subset of the complete code at a time (due to memory constraints).
- for testing of time-sensitive things, we didn't. Plain and simple. The hardware we used (8051 and 68302) was not always functional if it ran too slow. That sort of debugging had to be done initially with a CRO (oscilloscope) and (when we had some more money) an ICE (in-circuit emulator).
Hopefully the situation has improved since I last did it. I wouldn't wish that pain on my worst enemy.
Solution 2:
There can be a lot to be gained by unit testing in a PC environment (compiling your code with a PC C compiler and running your code in a PC unit testing framework), with several provisos:
- This doesn't apply to testing your low-level code, including start-up code, RAM tests, hardware drivers. You'll have to use more direct unit testing of those.
- Your embedded system's compiler has to be trustworthy, so you're not hunting for bugs created by the compiler.
- Your code has to be layered architecture, with hardware abstraction. You may need to write hardware driver simulators for your PC unit testing framework.
- You should always use the
stdint.h
types such asuint16_t
rather than plainunsigned int
etc.
We've followed these rules, and found that after unit testing the application-layer code in a PC unit test framework, we can have a good amount of confidence that it works well.
Advantages of unit testing on the PC platform:
- You don't face the problem of running out of ROM space on your embedded platform due to adding a unit testing framework.
- The compile-link-run cycle is typically faster and simpler on the PC platform (and avoids the 'write/download' step which can potentially be several minutes).
- You have more options for visualising progress (some embedded applications have limited I/O peripherals), storing input/output data for analysis, running more time-consuming tests.
- You can use readily available PC-based unit test frameworks that aren't available/suitable for an embedded platform.