Continuous Delivery and Code Quality
Developing software is often said to have two aspects: doing The Right Thing, and doing The Thing right. Lean-software development principles and Continuous delivery, which we both practice at Ingemark, address these aspects very effectively.
The central idea of continuous delivery is ensuring that the software can be reliably released at any time. This idea has many consequences, and the ones that I particularly like are the effects on the quality of produced code. Let’s examine some of these effects.
To be able to continuously deliver software, we have to ensure that we never break any existing functionality when making changes to the code. In order to do that, we avoid touching the code that already works. How can we change or add functionality without touching the code that already works? We can’t, unless the code is written in a way that allows this, honoring the S.O.L.I.D. principles and/or being simple in Rich Hickey’s sense of the word.
Continuous delivery makes us think about testing more clearly. The kind of testing we need is the one which ensures that a continuous stream of changes we’re deploying to production will not cause any damage. Large automated-to-manual tests ratio seems to be the inevitable consequence of this. Furthermore, maintaining a large number of efficient automated checks increases our ability to recognize the real value and effectiveness of any particular test, automated or manual.
Note that the goal of testing as stated above does not say that the code we deploy to production has to be bug-free, only that it must not cause any damage. This is quite significant because it leaves us with the option to deploy changes to production and use so-called feature toggles to try them out (i.e. really test them) before making them publicly available. Separating deployment from feature release is an essential part of the practice. And this brings us back to the matter of code structure and quality, because the code in which changes are made in a way that both the old behavior and the new one has to co-exist for some time emphasizes the need for good structure and quality.
Of course, writing code like this is easier said than done. However, every time we improve our code in order to accommodate a change and the continuous delivery process, we learn something useful which we will most likely be able to reuse in the future.