After my post about unit testing I decided to give a try to check. Although I don’t like the syntax tremendously, it works quite decently and it’s used by many projects so it should be safe enough to use and debug.
There are a few issues with the software I’m writing testcases for, that lies in the design of the software itself. After these findings, I guess it’ll be a good idea to write some suggestions, so that others might actually find it useful to read my blog, from time to time.
The first problem is that even the internal functions seems to work with high-level structures. While it’s nice to have functions act directly on high-level structures, it’s a bit of a problem to test them if you need to fill in a properly-configured structure full of data, just to make sure the parser is parsing the buffer correctly.
For this reason, my suggestion here is to break apart functions, one function has the interface that the users will use, with the high-level data structures and all the nice parts, and one acts directly on the lowest-level possible, so that testing becomes then very possible.
For instance, if you have a function that is given a structure, which contains an array of characters as a buffer, and a pointer to character with a value to extract from the buffer, it’s easier for testing if the function were just an interface to a lower-level one that acts on two characters arrays rather than on the high-level structure directly.
Another problem here is interfacing with visibility-enabled interfaces. The idea of unit testing is not, obviously, just for user-facing interfaces, but also, even more importantly, for internal interfaces. This is why even software that results in a final executable, rather than a library, should make heavy use of unit testing. Unfortunately, if you do use visibility for your software, linking the shared library will disallow the tests from properly executing.
To solve this last part, the easiest way is to make sure you’re linking against the static version of libraries, even commodity ones. Since visibility is applied at link stage, the static version of a library will not apply it to the functions before linking to the test, allowing access to the internal interfaces.
A software properly designed for unit testing is most likely to be solid especially when porting it to different systems, or when a new version of its dependencies is released and the behaviour changed, deliberately or not.