2024 Public Training Schedule
December 9 – 12, 2024 – Agile Analysis and Design Patterns
Half-Day Sessions
(c) 2024 To Be Agile
I’d like to wrap up these Seven Strategies for Increasing Code Quality with a strategy that kinda sums up all the rest of them—keep code testable.
Untested software carries a great deal of risk. If a developer who implements a feature test it manually only once then that feature may be affected by other changes in the system later. The prudent thing to do is to test and retest the system as it’s being built. This is entirely impractical for all but the most trivial systems if testing is a manual process.
One of the biggest values that I see coming from the DevOps movement is that automating software verification can significantly drop the cost of building and extending software. In many ways, this aspect of DevOps really fulfills the promise of Agile.
Automating software verification is the only way that I can see to achieve the first principle of the Agile manifesto which states, “Our highest priority is a satisfied customer through early and continuous delivery of valuable software.”
But even more important to my mind than having reliable regression tests is having testable code. Testable code is the code, not the tests and it’s possible to write testable code without writing any tests at all by simply answering the question in your mind, “if I were to test this code how would I do it?” And if the answer is simple then you know you have testable code, if the answer is not simple then try again.
Not coincidentally, testable code is code that has the CLEAN code qualities that I’ve been discussing in this series of blog posts.
Classes that are cohesive are more straightforward to test because there aren’t multiple issues that can interact and cause side effects. Likewise, correctly coupled code is also straightforward to test because we can easily replace external dependencies for test doubles. Encapsulated code also means that we’re not going to be suffering side effects between other parts of our system and assertive code means that the behavior and the data for the behavior are in the same class, making them more straightforward to test. Finally, nonredundant code means that we aren’t repeating tests throughout the system, which greatly simplifies testing.
So CLEAN code is testable code and testable code is CLEAN code. I find almost universally that as I improve the testability of my code I also improve my code quality. This makes software more straightforward to work with and extend in the future.
Software quality doesn’t just happen nor can you force it to happen using heavyweight processes like Waterfall. Software quality comes from understanding a problem and modeling it accurately. When we can do this we build systems whose cost of ownership is lower and therefore more cost-effective.
Note: This blog post is based on a section in my book, Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software.
Previous Post: « Name Things Well
Next Post: Why Practice 6: Write the Test First »