Why I Write Tests
I’ve had a few folks ask me if I really write tests for all my projects, like I mentioned in the last line of my second email in You’re Not Refactoring. Really?
Really, even on personal projects. I write tests because I’m really good at writing buggy software. I’d bet I’m better than you.
I’ve written those bugs that waste hours of time until I found the one missing (or added) bit of punctuation. I’ve written bugs that first-year programming students have caught. I’ve written so many of those really obvious bugs that my boss notices with the first glance that you’d be amazed I’ve never been fired. Bugs that confused my users into thinking they made mistakes. Bugs that ate data. Bugs that corrupt data silently. And lots of those little changes that broke that totally unrelated thing over there that, wait, yeah, it is actually related in this one tiny way. Bugs that would be really obvious if I’d remembered that one bug in IE6, if I’d remembered the API, if I’d remembered what my own code from last week looked like.
I write tests because I’m imperfect and I hate breaking things. I take code seriously and I’m happy when I write the best code I can. When I’m slipping in errors, when I’m wasting the time of myself and my users, and when I’m just plain afraid that I might be introducing bugs, I’m not writing good code. I don’t keep anything on my nightstand except my glasses, because I know I’m just going to knock it all off in the middle of the night when I’m groping for my glasses. I don’t want to set myself up to fail.
Testing isn’t everything, and I’ve talked about its limits. But it’s saved my bacon often enough that I feel like I’m taking needless risks when I don’t write tests.
Yeah, OK, fun little one-off scripts don’t have tests, but that script is also about the largest I’ll let code get without test. Read the comments, someone found that I left a bug lurking to shoot myself in the foot when I tried to expand or reuse the code.
I don’t want to write buggy software, but I know I will, so I write tests and then I build things that are far less buggy. I don’t test my personal projects out of a sense of obligation, I test them so I can relax and have fun building cool things.
That’s why my advice is always to start small with tests. Test what you can easily, you don’t have to write exhaustive tests that cover all possibilities on all your code. Write a happy-path test for when a function or method works right, and cover one or two ways things can go wrong or be misused. A few weeks or months from now when you break it in some silly way or don’t remember how it’s supposed to be called, the time you invested in tests will pay dividends. When some you narrow down a bug, write a test that exercises it, fix the bug, and smile as your test passes: that bug isn’t going to slip back into your code again. You’ll write better code without the stress. Trust me, I know.