Getting started with some new technology is always a daunting task. The only way you’re going to learn is if you teach yourself. Make sure to free yourself from distractions and get a cup of coffee so you can think clearly. When there are lots of unit testing frameworks and you need to evaluate what your requirements are going to be. For beginners it’s not always clear and you’re going to have to sample the available options.
- C++: Boost Test Library, Google Test, CppUnit (C++ Unit Testing Roundup)
- Objective-C: OCUnit, GTM iPhone Unit Testing, GHUnit
Most computer science courses don’t explain how to write testable code, they focus on the output matching. Students assume that if my code displays X and I’m trying to display X, then the code must be correct. Testable code can be hard to master, but it’s worth the effort. There’s two important aspects of unit testing that I’ve discovered.
a. A unit test, or a set of unit tests, validates that the function you just wrote works like you think it works. It takes microseconds for the computer to tell you if something works or not, and it takes you seconds or minutes to validate if it works. Your time is valuable, let computers do the grunt work of testing and you’ll have more time to write code.
b. Unit tests force design testing. High-level designs don’t translate into direct code without usability issues. As you write and test code you will find that a function should take X parameters instead of Y parameters, or that the function name doesn’t match the functionality it provides. Take the time to fix your design and you’ll have code that’s easier to use and better documented. The sooner you fix design issues, the more time you’ll have to work on features.
I still haven’t answered how to write testable code. Getting started is a matter of baby steps; take two steps at a time, and soon you’ll be walking.
a. Isolate the basic functions that have clear input and output. Write a test that provides a function with good input and bad input. Think about what additional functions you’ll need to prove that the function you’re testing works as expected. For example, in order to test a setter function, you’ll need a getter function. As you write more tests, refactor common tasks into helper functions, so that you can spend more time testing functionality instead of writing boilerplate test code.
b. Make sure you document each function as you test it, if you don’t write comments now, it’s never going to happen. Documentation is best when the details of the function are fresh in your mind and you can explain the edge cases.
Not everything is easy to test, but don’t be discouraged, since the tests you write will begin to validate that your code works as documented. You’re making progress and it’s going to get easier as you write more tests. Another benefit is that you’ll have higher quality code that you can rely on into the future.