Let There Be Tests!
I wrote two tests yesterday in Python's unittest framework. Each was less than 10 lines of code. It took me almost a week to get those two tests running, and I went home super-excited about it. Am I the world's worst programmer? (I can confidently answer, "no".) A super-newbie? (No, I've been programming professionally for 15+ years.) So what in the world have I been doing? Please allow me to elaborate.
The tests utilize helper objects I wrote (in Python, several hundred more lines of code) running on a jython interpreter so that I can utilize Code Composer Studio's (CCS) Debug Server Scripting (DSS) tool which is written in Java but has a jython interface. I use DSS to interact with the code under test that is running on a circuit board on my desk to determine (for example) when a function has been entered and what parameters were passed to it.
Further more, my tests need to send movement commands to the circuit board via a ROS node that translates ROS topics into UDP packets. This would usually be trivial with "rospy", however, because I'm running jython, I can't use rospy which is written for CPython. Instead I have to invoke the "rostopic" command-line tool. Python's subprocess library should do the trick, but it's only partially implemented in jython 2.5 which is what comes standard on the Ubuntu distro we're running on our desktop machines so I have to manually install jython 2.7.
Eventually I can send my movement commands, but the circuit board has been removed from the other hardware it usually interfaces with (such as motors) since it is inconvenient to have a 6-foot-tall robot (even a disassembled one) sitting on your desk. Besides, this is unit-testing and one of the advantages is that the testing can be done without depending on the rest of the system.
So I need to mock the sensor data that would usually come from those motors which I do with some C code, running in a separate process (or task) on the circuit board itself. I will also need the ability to inject data in a coordinated way to make the data appear as if it had come from the sensors in response to the movement commands. And of course what that data will be will be dependent upon the test itself. (e.g. Do we want to test our code's reaction to being commanded to move but the motors not turning? Or test what happens when we are commanded stationary but are moving anyway? etc.)
With the mock sensor code written, and the interaction to it, via DSS, wrapped in a python helper object, and the rostopic being published appropriately (again wrapped by a helper object) to send movement commands, and with jython 2.7 installed along with all the other tools such as ROS and CCS/DSS which I was already using to do development... I was finally able to run a test.
Now for the cleanup code between tests. After all I need to be able to return the system to a known state before running my second test. Oops! It turns out jython (even the version 2.7 I updated to) does not call the __del__ method when objects are destroyed, and the code under test hangs if you issue a DSS "restart" command. More experimenting and many google searches later I have abstracted the ugly details of "cleaning up" and now I can run my second test.
*sigh* So much for the KISS principle.
(Allow me to take a moment to say I hope I don't get into the following situation depicted by this it's-funny-'cause-it's-true chart...)
Obviously I'm not stopping with just two tests, that's why I left work feeling invigorated yesterday rather than beaten down. All that work was not just to run two tests. At last we have a couple valid examples and a strong foundation on which to base many more tests that can be run automatically when people make a pull request (PR) against the repository. At last we have a framework that will allow us to weave a safety net of unittests around the complex algorithms we have been unable to test up to this point except by running a robot around and forcing error conditions it is usually designed to avoid. At last I can say: "Let there be tests!"
I am so stoked to read this, for a bunch of reasons! Congratulations Man!