Testing is Hard28 Jan 2017
One of my friends and colleagues writes for the Project Management for Developers blog. He recently wrote an article about the importance of testing. I want to respond to his blog post and provide some additional insight into testing from a developer perspective.
I’m going to talk mainly about unit tests here because I believe unit tests are the foundation and most important part of any test suite. But most of the ideas apply equally well to other types of tests.
Time & Coverage
Somehow, it’s always easy to find an excuse not to write tests. You’re spending too much time on tests. That component isn’t testable. You tested it manually right? We need to get this out. It’s just too hard to test. The code’s too old. It’s not worth it. If you’re a developer, you’ve heard pretty much all these excuses at one point or another.
So here’s my advice: Just write the tests! Wherever you think you don’t need tests, that’s where the bug will be. Every time. It’s almost always worth it to have tests. And as you gain more experience, you’ll find testing to be quicker and easier than you thought it was. Tests catch your bugs when you’re writing code, and they prevent you from breaking the code when you add a feature a year or two later.
Now that I’ve convinced you how important tests are, I’m going to backpedal a little bit. You’re not likely to ever reach 100% coverage. In fact, 90% or even 80% will be really hard to hit. So be smart about what you test. Test the components of your code that have the most logic and are most likely to break. And write a test whenever you fix a bug.
I mentioned that as you gain more experience writing tests, it becomes quicker and easier. It’s true, and one of the main reasons for this is that you start to recognize patterns in your code. When you’re working with old code that doesn’t have unit tests, you’ll initially find it hard to test. You need to find what Michael Feathers calls seams. Places in your code where you can inject a mock or a stub and run some tests.
As you start to look for these seams in older code, you also start adding them to new code as you’re designing it. You don’t want to have to refactor your new code just to test it later on, so you make it easy to test from the beginning. You’ll start thinking about things like dependency injection when you’re writing your constructors. Test driven development forces you to write code that’s testable. But even if you’re not doing strict test driven development, your code will be easier to test if you think about how you’ll test it when you write it. This means less time spent testing, better test coverage, and more reliable code.
Think About your Client
No matter what type of application you’re working with, well-written tests provide a huge amount of value that is not immediately apparent. When you write tests, you’re making an investment in the quality (especially long-term) of your application. Your clients are always going to want their code sooner, and tests may seem like a bad trade-off when it delays this week’s release a couple of days. This is why it’s important to explain to your clients the value that tests provide. In the long run, you’re better off having tests, and it may even increase your team’s development speed down the road.
As a software developer, your job is to deliver working code to your client. Tests are one of the tools that enable you do do this. If you’re delivering code that doesn’t have good test coverage, you’re much more likely to be delivering buggy code. Experienced developers know this inherently because they find bugs pretty much every time they write tests. As a professional software developer, it’s part of your job to understand this, to help your client make informed decisions, and to deliver well-tested and bug-free software.