I have heard it said from a number of sources that the largest source of defects and the ones that are the most expensive to fix are our misunderstandings of requirements.
Requirements are essential. If we build the wrong stuff, something the customer doesn’t want or need, then it doesn’t matter how beautiful our code is, we will still have missed the mark. For me, software development has been a major awakening at how ambiguous language is.
We talk in vagaries but you can’t do that in a computer program, you have to be precise and specific. Because of this, there is something often lost in translation between the written requirements and their implementation. It turns out that this is the biggest gap in technology between figuring out what we want and then implementing it.
Fortunately, there is a technique in Agile software development that addresses and largely mitigates this issue. It is called acceptance test-driven development (ATDD) and when we do it properly it helps us not only get clearer on the benefits of what we want to build but also define it in such a way that it is understood among all stakeholders and crystal clear when the system has been updated with this new capability.
All of this doesn’t come for free. There is an extra effort involved in setting up yet another system and then maintaining it, keeping it up-to-date so that it becomes a dashboard that keeps everyone informed as to the status of the system and what features are implemented as well as the ones that are yet to be done.
I find this does great things for a team’s morale because we all can see very clearly where we stand. When all of our acceptance tests pass, it means that the feature is complete because we have fulfilled all of the acceptance criteria. We can see at a glance what parts of the system have been implemented and what parts are still yet to be done.
One of the things I find most valuable about doing acceptance test-driven development is that it helps me get really clear on the benefits of what I’m building and reach consensus with my Product Owner and/or stakeholders on what a feature should do. Often times, just the process of getting people on the same page with the feature will not only ferret out misunderstandings ahead of time but will also help us refine the feature so that we’re getting the maximum value from our efforts.
One of the main reasons that acceptance test-driven development has so many advantages is that it frames the building of features in terms of a test or an assertion. It does this by letting you give a series of examples to the system and asserting that it behaves in certain ways.
This really brings us to the fundamental advantage of both TDD and ATDD, which is that it helps us build systems and features by example. This is actually how the brain works, we think in terms of examples so building out a feature by asserting an example of that behavior turns out to be a good way of creating software, a more natural way, and more in alignment with how the brain actually works. That has been my experience, anyway.
I find that it also shifts the conversation about what we’re building from the abstract to the specific and there are many advantages to that. When we speak in terms of the abstract, really anything is possible and anything could and might happen so it’s very hard to generalize but if we talk in terms of our past experience or in terms of specific examples then the conversation is much more grounded and easier to find logical flaws and easier to make the conversation more logically consistent. This also helps us build behaviors that are more consistent and more straightforward to build.
Clarity is of the utmost importance when we are building software. It seems like there’s an endless barrage of questions and trade-offs we need to address when implementing even the simplest feature so therefore we have to get really clear on exactly what we’re building and why we’re building it. I find that both ATDD and TDD are invaluable tools for helping me do this.
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 called Seven Strategies for Seven Strategies for Measuring Software Development.
Previous Post: « Why Practice 6: Write the Test First
Next Post: Know Who it’s for and Why They Want it »