Why do I bother writing tests? I can think of five reasons why writing tests is helpful. There are more sub-reasons under these reasons, but I think any other benefit of testing can be traced back to one of these five.
Testing helps prevent bugs
I personally find that the process of writing tests gets me into a mindset of trying to think of all the paths through a piece of code, including all the ways the feature I’m writing could be abused. This means that a feature I’ve written tests for is less likely to be buggy than a feature I haven’t written tests for.
Testing helps prevent regressions
It never ceases to amaze me (and humble me and embarrass me) how frequently I’ll write a new piece of code and then discover that my addition breaks some older, supposedly rock-solid part of the application. To take a recent example, I recently added a database column in an application, an act which broke a static page! Automated testing is great for catching unexpected regressions like this.
Testing helps improve design
For the most part, code that is modular and loosely coupled is easily testable. Incidentally, code that is modular and loosely coupled also happens to tend to be easily understandable. Testing is often said to encourage “good design”, which is another way of saying the it encourages code that is easily understandable.
Testing helps enable refactoring
Because automated tests help catch regressions, tests help make refactoring possible. Refactoring is not only helpful, it’s necessary. As an application grows, it’s impossible for the entire codebase to stay cohesive and DRY without occasionally taking a step back, observing any repetition and lack of cohesion, and refactoring to bring the codebase back to an acceptably DRY and cohesive state.
Testing aids the understandability of the codebase by serving as documentation
If I look at a piece of code I wrote 8 months ago and I don’t remember what it does, I can look to the test I wrote to help me understand what the code is supposed to do.
What testing doesn’t do
Notice how each of my headings starts with “testing helps” or “testing aids“. Despite these very real and valuable benefits of testing listed above, testing does not provide guarantees. Tests don’t catch every bug or regression. Tests don’t (and can’t) prove the absence of bugs. Tests can’t tell you whether your UI is user-friendly or whether your product has business value. But tests can save you a heck of a lot of time and money and toil.