As you approach the whole idea of adding automated tests to your code, you will see the benefit of safety but may wonder how much additional time you’re going to need to get that safety. If you ask some senior devs, they will smirk a bit (they usually do) and then tell you that any time invested now in writing tests will produce huge savings later. They are right, of course, but usually you just have to take their words for it. In this post I’m going to expand a little more on that suggestion so you may feel more comfortable about it (and start to smirk a bit yourself).
First of all, it’s not writing tests that takes time: it’s learning how to write them that does. You have to learn how yo use the available tools, how to mock service, how to expect exceptions, how to get fixtures, how to make HTTP requests. But as you move forward and get these skills under your belt, writing a new test will be a matter of seconds and the hardest part will become either decide what to test and/or improve your code to make it more testable.
Which may in itself sounds like another conundrum: why should I change my working code to make more testable? Well, thank you for asking, I can give you two answers.
- One: as we’re trying to explain in this post, tests will save you time in the long run so changing your code to make it more testable is part of the investment.
- Two: when you make your code more testable you automatically make it BETTER. You separate concerns, you make smaller methods, you define clearer return values. The effort of making it more testable will also improve its quality.
Once you have a good test suite ready, you may start refactoring. You can tackle the longer and more complex parts of your code and try to make them better. You may use known design patterns or just simply apply some reasoning and experience. You refactor with confidence and speed, as the tests will tell you when you break anything. Since the whole definition of refactoring is to improve the code quality (without changing its behaviour) it is clear that, as a result of this work, your code will be easier to read and to change, thus making any additional change faster.
The alert reader may raise a hand here, and warn about a possible catch-22. I just said that you may only start refactoring after having tests, but before that I said that you may have to change your code to make it testable. This is a very common problem which is nicely addressed by Michael Feathers in his famous book about legacy code, by providing a few tricks. A really short and poor summary of them is: make just the few smallest, safest changes that allows you to write the tests. Resist the temptation to change more than the bare minimum, and come back later when you have your tests in place.
Back to the main topic. Where were we? Ah yes: now you have a test suite, which gives you confidence, and a refactored codebase, which is easier to understand. Go on and try to make any change. See the difference? The speed gain you get will astonish you: suddenly there is a LOT of time that you do not spend re-understanding the code or re-testing everything else.
A final pro tip. You don’t have to go through these steps for the whole project at once. Whenever you have to work on any given part of it, add tests, refactor, and then do the work you have to do. By applying this approach constantly, your project WILL get better and you WILL get faster.
Qed. Smirk. Bye.