Bugs happen. For example:
And yet, the fact that bugs happen seems to be somehow controversial.
The Inevitability of Bugs
I recently heard about a group that had a policy that no one should enter bugs into their project management software because the developers were simply “not supposed to write any bugs.” This might just be the customer being risk-averse: they want a fixed-bid project because they want to make sure all their risks are tightly under control.
But while it’s an understandable concern, it’s misguided. First, because history has shown over and over that no matter how tightly things are controlled, it’s still possible for bugs to sneak in. Software systems are complex and no two interact in the same way, so unexpected outcomes are inevitable. But more importantly, it’s misguided because it is a terribly unhealthy way to run a team.
Wishful Thinking & Saving Face
If your project is not allowed to have bugs, then your project will have many, bad, and hard-to-fix bugs. There’s no wiggle room there at all. There are going to be bugs regardless, but when you ignore bugs’ existence, you prevent them from being fixed. They stick around and accumulate, and eventually the avalanche will bury your project.
Declarations like “there shall be no bugs” are so pernicious because they create an “us versus them” mentality. If the customer says “X is a bug”, such a rule incentivizes the developer to say things like, “That’s not what was in the spec.” Or you end up with developers who say a task is not actionable because it isn’t 100% completely unambiguously defined.
It also means that you can’t build a feature and then see how people interact and change it: suggesting a change is like suggesting something wasn’t done perfectly the first time. It means never learning from your mistakes, because you’re not allowed to acknowledge that mistakes exist.
Learning to Love Your Bugs
Instead, a healthy team will acknowledge that things are never perfect. When you build based on imperfect knowledge, inevitably things will need to be changed. If you accept that, you can work more effectively because you can talk about what’s wrong and what needs to be fixed (or what can wait until later.) You can accept that things won’t be perfect and engineer defense in depth—starting with automated tests in development going all the way through the process to monitoring in production, backups, and well-rehearsed disaster recovery processes.
Every piece of software is distinct from every other, and no one can predict how it will behave in the real world. That’s okay; we can iterate and learn. But we can only do that if we live in the real—and imperfect—world.