A Brief HistoryI recently wrote a unit testing framework for the NetBurner family of products based on the UnitTest++ framework. It's available on the NetBurner forums, and you you can watch an overview video on the framework, and one on how to write some simple tests against it. There's a lot of resistance to using Unit Testing in the embedded world. I hope to address some of the unique challenges of doing embedded UnitTesting. Since the NetBurner's claim to fame is its out-of-the-box support for TCP, there's a lot of code I reuse for every project and none of it is hardware specific. Every project I write has multiple processes, a tcp server, a web server, serial port debug output and a command processor to name just a few. It was helpful and not too difficult to write unit tests for all of my standard library that takes advantage of these facilities. It's can be less obvious how to write the unit tests when you start talking to proprietary hardware. The rest of this post is going to talk about one approach to doing that. Since most embedded programmers are familiar with programming devices over serial ports, that's where I'm gong to start.
Serial Port programmingOne very common programming task in the embedded world involves programming a device over a serial port. In this post I'm going to talk about a standard RS232 serial port but the technique can just as easily be applied to other RS flavors as well as SPI, I2C etc.
I was tasked with programming the Matrix Orbital GTT touchsreen, this device uses a binary stream of bytes sent to it over RS232 to invoke the API commands. Now of course I could still write unit tests by attaching the device, running the tests and seeing if things show up correctly. However, while I think that's very worth doing, it's more of an integration test than a unit test and since it requires a man-in-the-loop it's not an automatic test. It requires a working serial port and the actual device to program. I wanted a unit test that could validate a lot of my library without either one.
Without thinking about unit testing I might be tempted to create a TouchScreen class that just internally writes directly to the serial port. Of course I don't like writing to C APIs to begin with so I typically wrap up needed serial port functionality into a SerialPort class. It makes configuring all those pesky settings much cleaner. So then I might be tempted to just new up an instance of the SerialPort class and use that. That would still lock me into the single SerialPort class. I NEVER want to modify target code for the sole purpose of supporting unit tests. If I did I might be tempted to just modify SerialPort so that I could set flags and have it behave differently if unit tests were being run. There's a better way.