Brian McCallister tweeted "Current development speed is a function of past development quality."
It kind of summaries why I am passionate about code quality and taking the time early to do the right thing right.
According to me, code quality means code that does what it needs to do in a way so that it is possible to understand what it does and extend it when needed.
All systems have technical debt. The only difference is how much. And how much of the technical debt you are aware of. A problem with technical debt is that a decision that seemed like a good idea today can be a liability in a couple of weeks. We always learn and discover when a system is being developed and we have probably learnt something new in a few weeks time. This new knowledge tells us that a certain decision we took a while ago was a bad decision.
Technical debt is like gaining weight, it builds up slowly and you may not even be aware of it for a while.
I get stressed when seemingly simple things take forever to implement. An example may be loop holes I have to jump through before a task can be finished. Loop holes that sometimes are there for a good reason. But unfortunately, most loop holes I encounter don't bring any value. They are just annoying and a sign that something is wrong.
Being forced through unnecessary loop holes is bad. But even worse is working on a brittle system that breaks for no apparent reason at all. It's like building a house and ignore the ground work. The house will not be stable and it will break after a while. This creates stress due to bad quality.
Good quality reduces stress. The question is how to get there. What do you have to do to end up with a system of good quality that is a pleasure to work with?
The way to reduce stress, and at the same time increase development speed, is to make it dead simple to change or extend the system. Automate building it. Automate its testing to such a degree that you are confident that you haven't broken anything when others start using it.
One goal is to make sure that the manual testers have a boring job and never find any issues. If they find an issue, make sure that you implement tests that reproduce the problem before you fix it. This will save you from the embarrassment of delivering the same bug twice.
I test software I write as early as possible. The earliest possible time tend to be before I write any production code. The only way testing can scale is when it is automated. When I have put the effort into writing the test, I want to benefit from the investment during a long time. At least as long as I'm working with that particular system. Unit tests, integrated tests, and acceptance tests are therefore necessary to automate.
Writing tests doesn't lead to good quality in itself. The only thing the tests brings is a safety net. This safety net allows me to change the code until it is easier to understand, change, and extend. With the tests, I always know that the wanted behaviour remains while the code is being transformed. The result is that I am not afraid to refactor something. I will know within a few seconds if I broke something and can revert the changes if needed.
This doesn't work if I take too large steps or run the test seldom. Too large steps tend to be tasks that takes hours to perform while the safety net is broken. The solution is to define a vision of where I am headed, do some design and then work towards the goal in small steps. Each step is driven by a test at some level. Each test is written before the production code. This forces me to make sure that the tests I write doesn't know about the internal behaviour of the code. Not having knowledge about the internals allows me to refactor the production code without changing the tests.
The answer to the question "Why should you care about quality?" has to be because you want to do a good job and deliver value. Delivering value when you work with software development tend to imply delivering working software often. The way to do that is to develop the software as reliably as possible and as fast as possible.
My solution to a higher development speed is therefore to drive the development using testing and automation. This is why techniques such as TDD and BDD, and build tools like Maven and Gradle are important tools in my tool box.
I would like to thank Malin Ekholm for proof reading.