TDD for state machines
04 Jan 2013, 10:01
Jan Suchotzki (1 post)
I’m working on some smaller controllers and currently without any OS. This leaves me with the task that some time consuming activities need to be split into smaller parts. So main is not blocked for a longer time.
Any ideas how to better design/implement the modules so that testing gets easier and more maintainable?
Thanks a lot and enjoy embedded development in 2013!
PS: Hope the question isn’t too generic.
04 Feb 2013, 07:18
Arnd R.Strube (53 posts)
I have had good success using QPC / QPN, doing most testing off-target with CppUTest. You may want to have a look at the book “Practical UML Statecharts in C/C++, Second Edition” to get an idea.
Whether or not using the QP framework is an option in your situation obviously I can’t tell, but even if not, the book is the best I’ve seen on state machines, especially hand-coded ones. If you can use QP, you will be thrilled by how simple hierarchichal SMs can be in code.
As for your question, I even run multiple tests on single-instance SMs in C, because the initialization will put it back in the initial state cleanly. In CPP, I tend to use new/delete for tests, even if production code does not.
Also, you can test your state machines in and out of task. Generally, I let the state machine and my tests run in the same task, but it is possible to let the SMs run in a separate task (main task for tests)
Finally, QP uses the idea of a “Board Support Package”. This basically contains calls for all the I/O stuff. It allows you to test off-target whether certain calls have occured, without any need for hardware.
Off-target, I have put in tracing macros that would allow me to tell which event occured in what state, but I’d recommend against using these in tests. You don’t want to re-write your tests every time you redesign the inside of your SMs. Generally, I find it a better approach to test for the outcome of a certain sequence of events. About the only exception is the “initial” pseudo state. Apart from that, I use the trace prints for manual inspection rather than for testing.
I am doing this out of personal interest at the moment. My target is a TI eZ430 Chronos. I have one active SM (own task) and a bunch of “apps” that run inside the main SM (this makes sense because only one “app” can use I/O at any one time).
I am not using SMs at driver level yet. I would like to run unit tests at that level, too, but am not quite sure yet as to which tools to use. Anything like “printf” or “cout” would pretty much have to limit itself to “PaSS”, “FaIL” and the number of errors, if any.
I hope this might give you some new ideas,
|You must be logged in to comment|