Introducing a new methodology in an organization is an investment. As with all investments, you first see what you give up, and only later see what you get. As humans (and as any biological creature), it’s against our instincts, because the future is always more vague than the present, and so any investment feels like a risk (and in fact, it is always a risk, to some degree).
Because investments are against our nature, we tend to make only small improvements to our existing practices. And because we’re afraid of big changes, we convince ourselves that our problems are facts of life that cannot be avoided. Most people in this industry believe that bugs in software are a fact of life, and there’s not much we can do about it. So are customers’ complaints and a high rate of failing projects.
This fear of change leads most managers in the software industry (at least most of those I encountered) to focus mainly on the short-term: get this release out as quick as possible. The cost of fixing the bugs we introduce when working under pressure, and with only a wary safety net of last-minute testing, rarely cross our minds. Let alone thoughts like: how happy our customers would be if we could release new features quickly while keeping the quality high.
So let’s ask ourselves this courageous question: Can we write bug-free software?
Obviously, there’s a good chance that we could write a “Hello, World” program without bugs. But not less obvious, is that as the complexity of our software goes up, the chances for bugs get high very quickly. Let’s try to dig into this question, and maybe we’ll find some interesting insights on the way (even if the answer to the question would still be “No”).
What’s a bug, anyway?
As much as the fact that bugs are inevitable is well known, there’s another fact that everyone would agree upon: The computer does exactly what it’s been told to. So, wait a minute! If the computer does exactly what we’ve been telling it, then how come the computer makes mistakes at all?!
There’s a known true story that happened in the 40’s about a moth that was trapped in a relay (an electromechanical switch that was used in early computers) and distorted the computer operation. This story is usually attributed as the first time the term “Bug” was used. (According to Wikipedia, the term was coined before that story, but who cares? ). Here’s the real bug report:
So bugs can be a physical, mechanical or electronic issue that causes the computer to malfunction, but these are really the rare cases. Usually when we say “Bug” we refer to something completely different.
People often attribute bugs to programmer mistakes. While this if often true, it’s not always the case. If a programmer wrote “-“ instead of “+” inadvertently, then yes, this is a programmer mistake. However, if two programmers work on 2 interacting components, it could be that each programmer wrote exactly what he intended but not what the other developer intended, and so the components won’t interact as each of them expected. No one made a mistake – it’s simply a misunderstanding. Such misunderstandings can happen not only between developers, but also between developers and product managers or the customers (or any other stakeholder).
I like to think about bugs as expectation gaps (or intention gaps). In case of a programmer mistake I can say: “Even though I told the computer exactly what to do, I expected it to do something else”.
Well, in fact, there’s never a single programmer (or user) who tells the computer exactly what to do. Instead, we (both as developers and as users) rely on software that other developers created, either in our team or by 3rd party vendors (including the OS, compiler, 3rd party tools etc) and in conjunction we’re all telling the computer what to do. So we can generalize the above sentence as follows:
“Even though I, with conjunction with many other people, told the computer exactly what to do, I expected it to do something else”
So as you see, it all comes down to expectations. It can be that I wrote something but meant to write something else; it could be I that I expected the library I’m using to behave differently; it could be I expected the user to use the software in one way and not the other, or it could be that the customer didn’t explain correctly what he wants, and expected something else than what he got.
How Agile address expectation gaps?
Though not a silver-bullet, agile methodologies (e.g. SCRUM, XP) provide several means to address these expectation gaps. Most of them have one thing in common: they shorten the feedback loop. For example, 2-4 weeks iterations which result in a working software allows the customer to provide feedback on the gaps between his expectations and the working software often and sooner. Another example is continuous integration which provides feedback for developers about the state of the software and reveals expectation gaps between developers or teams early.
Even though this short feedback loops helps keeping the expectation gaps manageable (and not letting them bloat, as often happens in long waterfall projects), it still unreal for the customer, or even the QA, to verify that all of their expectations are met.
So what can we do about it?
Our collective experience in the software industry taught us that specifying all the expectations in advance doesn’t help much. There always be things we didn’t think about, especially when the software is complex (and most software is complex). And even if we wrote an excellent specification document that details our expectations exactly, there’s no good way to verify that the produced software actually fulfills these expectations.
However, if we had a way to write our expectations in a way that can be verified reliably, then we would be much better off. In fact, we could specify our expectations gradually, each time adding just one or a handful of new expectations, and then verifying that all our previous expectations are still met. This way we could add more realistic expectations as we go, not having to imagine a complete and complicated system at one shot.
Specify + Verify (expectations) = ATDD
But how can we write our expectations in a way that can be verified reliably? Obviously if we want to it be reliable it ought to be automated. But, on the other hand, we want to write our expectations before we implement them, so how can we automate something that doesn’t exist yet? Well, the answer to this is ATDD (Acceptance Test Driven Development), which you can read about in a previous post of mine.
So can we create bug-free programs or can we not?
Expectations are a subjective thing. And assumptions (which are also kind of expectations) can not be completely avoided, and we can never specify all of them. For example, when I’m about to sit on a chair I expect that it won’t collapse under me (as long as it doesn’t look shaky); When I buy a Pizza, I expect it to not be poisoned (and probably I won’t specify these as my requirements from a chair or a pizza). One cannot live without making assumptions all along, and expect the world to behave as his experience taught him. Different people will always have different expectations, and no one can ever manifest all of his expectations as all one’s expectations is equivalent to his whole life experience. (I’m being a little philosophical here, don’t I? ). Therefore there will always a chance for misunderstandings and expectation gaps.
Well…, so the bottom line is that I don’t presume we can avoid bugs completely. But ATDD helps us reduce them to really the bare minimum! And this reason alone is worth being courageous enough to make this change! But there are many other benefits to ATDD, including project status visibility and clean and maintainable code…
ATDD + Coaching = E4D Solutions
I once saw the following definition for “coach”: someone who makes you do things you don’t want to, in order to help you get where you want to get. As I stated above, introducing a new methodology is against our instincts and requires courage. But courage alone is not enough, because courage usually don’t last long. Coaching helps maintaining the courageous decision until your goal is reached.
E4D Solutions provide coaching and mentoring for introducing ATDD in your software development organizations (as well as mentoring for TDD, SCRUM and more). In addition, E4D provides complete solutions by expert consultants, which extend the entire software development aspects including architecture, ALM, Testing and experts in all of Microsoft technologies. Contact E4D for more information.