Preventing Software Bugs from Ever Occurring
As a kid, I remember being frustrated by a fly that was keeping me awake in the night. It was one of those huge monstrous ones that made an electrifying buzzing sound as it flew around the room.
I recall my dad teaching me a little trick. He told me to turn the light off in my room, and switch on the light in the hallway. The fly was attracted to the light in the hallway and flew towards it. He then told me to open the front door, turn the hallway lights off. The fly duly flew towards the brighter street light, allowing me to get back to sleep.
What really happened was that my dad understood the nature of bugs. He knew they were attracted to light. So rather than teaching me to fight the bug, he taught me to control the lights which controlled the bugs.
I learnt a big lesson that day:
If you understand bugs, there is no need to fight them.
Nowadays I use the same technique to prevent all sorts of bugs in the bedroom. When mosquito are around, I turn on the hallway light for 30 minutes before bedtime, and I am bite free in the morning.
As Benjamin Franklin once said:
“An ounce of prevention is worth a pound of cure.”
But What about Bugs in Software?
What if you could understand the nature of software bugs, and therefore understand how to prevent them? Is there a “light switch” trick for software bugs?
Turns out, there are only 3 types of bugs. Yes, you read that correctly, 3! Each has a “light switch” trick, which I like to call the highest impact quality function. In this article I will discuss a model that I use to classify these 3 types and what these quality functions are.
Bug Type 1: Implementation Defect
Description
The specification was correct, but the implementation was defective.
At first glance, this might look like the most common type of bug, but it’s actually quite the opposite! As this study shows, only 15% of defects occur at the implementation stage. However, the study does not consider regression bugs, and in my model of bug classification, I consider regression bugs to be incorrect implementation. Even still, this type of bug is the least common of the three in my experience.
Common Causes
Regressions
Bugs lurk in large and complex codebases that are full of cobwebs. The industry average is 15–50 bugs per 1000 lines of code! Even the most skilled developers can introduce bugs as they can’t see the impact of their changes.
Smelly Code
“Smelly Code” is considered an indicator of weaknesses in the code design that are likely to introduce bugs. Some of the factors that contribute to this are management pressure to go faster, laziness, and above all — ignorance.
Insufficient Testing
Timelines get tight and teams need to release implementations quickly. As a result, testing (manual or automated) is skipped or hurried, which means bugs that spawned at development time can casually stroll into production.
Highest Impact Quality Function
Test Driven Development
Test Driven Development (TDD) is a development-stage practice that codifies the incoming specifications and turns them into executable specifications.
This practice ensures that code which works as specified today, will continue to work as specified in the future as others maintain it, making it the most effective prevention to Regressions.
Practicing TDD encourages the use of principles such as the separation of concerns, design patterns and refactoring. All of which are all known to create clean code, or at least less Smelly Code!
It also encourages practices like automated builds and continuous integration which allow you to maintain speed even in the face of time pressure, thus reducing the Insufficient Testing problem.
All of the above benefits are known to reduce defects between 40–90%. That’s HUGE! This makes TDD the highest impact quality function to prevent implementation bugs.
What baffles me is this:
Test Driven Development has been around since the 60's!
How is TDD not a standard-issue weapon for all developers today?!
Should you TDD EVERYTHING? Not really, TDD should not be a dogma. You need to consider the opportunity cost and your team dynamics.
If you’re not already doing it, then start using TDD to clean up your code and the benefits will fall into place over time. Just like with the light switch trick, you have to be patient!
Type 2: Incorrect Specification
Description
The specification was incorrect, therefore the implementation is incorrect.
A Cambridge University study shows that 50% of defects occur in specifications. The same message is resonated in other studies. Mistakes made and discovered later in the cycle can cost 50–100x more than if they are discovered earlier. Despite being the largest source of bugs by far, specifications still go into development unchallenged. What gives?!
Common Causes
Inadequate Communication
I mentioned above that “specifications are the communication of assumed value”. When the specifications don’t contain details that are known to the author, then bugs can occur due to misunderstanding.
Inconsistency
Sometimes new specifications are written that conflict with older specifications. When this happens, a bug will magically appear at the development stage (if you’re lucky), or in production.
Highest Impact Quality Function
Behaviour Driven Development
Behaviour Driven Development (BDD) is a team-wide development methodology, with a heavy emphasis on creating a shared understanding between business people and technical people.
BDD starts with deliberate discovery sessions that involves people from all disciplines. Together they flesh out detailed scenarios using exercises such as Example Mapping from Matt Wynne. The output of such exercises leads to a deeper understanding of the domain, and also to creating Specification by Example documents that express the system behaviour. These exercises and artifacts are very effective at addressing the Inadequate Communication problem.
Developers use these specifications to model the domain model using a technique called Modeling by Example, or Event Storming from Alberto Brandolini. In turn, a ubiquitous domain language forms which speeds up development by reducing the translation cost from requirements to code. The ubiquitous domain language is excellent at preventing the Inconsistency of specifications.
What’s awesome is that the very specification document becomes the actual automated test. What does all of this add up to?
Behaviour Driven Development can reduce specification defects to from 50% to 2%!
Wait, what?! 2%?! (source) If this methodology is not the highest impact quality function to prevent specification bugs, I don’t know what is!
BDD is quite intuitive and you’re probably doing parts of it already. It doesn’t force you to draw thousands of UML diagrams, and is pretty low friction to adopt.
A word of caution however. BDD is a very misunderstood practice. Many people think it’s just a testing approach but it’s far more than that. I would encourage you to read Aslak Hellesøy’s view of BDD.
If you’re confused on where to start, then just start by having conversations in deliberate discovery sessions. These are the most important aspects of BDD. If you do one thing only from BDD, it should be to have these conversations.
Do this for a few releases and see with your own eyes the number of defects reduce. You might even get some stress relief and enjoy it!
Bug Type 3: Missing Specifications
Description
The specification was missing, therefore the implementation is missing.
Simply put, these are the scenarios you never imagined when designing your product. They are otherwise referred to as the “unknown” type. Their impact is unpredictable and can range from embarrassing to catastrophic.
Common Causes
Insufficient Research
You’ve probably heard the phrase that that when you assume, you make an ass out of you and me. Assumed value is no different and can come with tricky nuances. When these are not researched, an unknown bug hatches!
Ignorance
Someone realizes the “implementation is wrong” at release time, even though the expected behavior was not specified! Sound familiar? These bugs come into existence due to the lack 0f specifications.
Highest Impact Quality Function
Behaviour Driven Development
Huh? Again? Yep!
The deliberate discovery stage of BDD is a great way to use the wisdom of crowds and identify unknowns. The discovery stage is not unidirectional but rather, it’s iterative. It is intended to create questions as well as answers. Some of these questions require further research to feed back to the team. This cycle of interactions is an excellent way to deliberately discover unknown specifications.
Summing it up
For the foreseeable future, as long as we create software, we will inadvertently create some bugs. But just my old man can share with me a proven technique to save my night’s sleep, so we can learn some great techniques to save us a lifetime of fighting bugs.
The trick is not to think about how to fight them, it is to understand how to never invite them into a fight in the first place.
“The greatest victory is that which requires no battle.”
― Sun Tzu, The Art of War
I will be writing more on other quality functions that you can put in place to increase the quality of your product.
If this theme and my comments resonate with you, please let me know by clicking that heart icon and recommending the article to expand the reach of this message.
Let me know if you have any questions or thoughts in the comments below.