Behavior-Driven Development (BDD) offers compelling benefits, which most groups completely miss out on. I don’t mean “they’re doing it wrong”. The reasons form a complex web, which we can start to understand by looking at one common failure mode: what often happens when programmers unilaterally decide to adopt BDD on their project. This approach tends to fall into the trap of comfortable mediocrity; but with some small changes, they can get much more out of their choice to “do BDD”. They can avoid some common frustrations as well as the bad taste that failing to “do BDD” often leaves in their mouths.
Programmers often try to introduce BDD into their projects with the goal of “building the right thing” more often. Whereas evolutionary design (perhaps TDD in particular) helps them “build the thing right”, BDD, they reason, will help them “build the right thing”. This mantra neatly encapsulates the communication gap between the people building the software and the people asking them to build it: the picture in the collective minds of the programmers doesn’t match the picture in the collective minds of the various stakeholders. Not only do I see this time and again, but I also routinely see groups with no strategy for managing the risks resulting from this difference in understanding. I advocate adopting BDD precisely to manage this risk!
Unfortunately, well-meaning programmers who start “doing BDD” become quickly aware of the limits of their autonomy and influence. In the best case, they struggle valiantly to influence the larger project community, they mostly fail, and then they retreat to their code. In the worst case, they never look outside their code at all! In any case, they tend to focus their BDD practice on the code, which leads them to (at least) two significant mistakes:
Of these two, the second presents a much bigger distraction, so I’ll leave the first one for another time.
Imagine a group of well-meaning programmers energetically starting to “do BDD”. They download tools like SpecFlow. They read about Gherkin, the syntax for writing examples. They write a few examples for their system and, after some battling, extract the missing API that they can connect to their SpecFlow steps that finally make those tests pass. They celebrate briefly, then hook their feature test suite into their continuous build and deploy system. They argue for a while about whether a failing feature test should cause the build to fail. Maybe they generate some nice reports showing all the passing and failing feature tests because somebody (somewhere? but who? and when?) could use those reports to show progress towards a product we could feel proud of. Gradually, over a period of months, they feel some vague sense of success, because they have more-precise specifications, more test coverage, and have something new to show their stakeholders.
And then, quite suddenly, the illusion falls apart.
External users still report just as many “bugs” as they used to. The group uncovers disagreements about how a feature is meant to behave. Sometimes the system works “as designed” and the users “simply need to be educated”. The group fields urgent demands for features that nobody had even talked about building yet… wasn’t BDD supposed to fix these problems?
The product owner shows no real interest in writing tests in Gherkin (didn’t we get rid of COBOL in the 1990s?), so that responsibility falls to the programmers. Two weeks later, when the product owner sees a completed feature, they point out 12 problems, ranging from minor nits to major misunderstandings about what “we agreed” to build. The programmers see that they have to throw away and redo 30% of their work… wasn’t BDD supposed to fix this problem?
After a few months, the feature test suite starts to take 15 minutes to run. The programmers notice that this has become a bottleneck, because they’d agreed not to merge a pull request until the feature test suite runs to completion. They’d even automated this! This delays urgent, small fixes, causing the group to work around “the process”. This erodes some people’s confidence in the value of these “BDDs”. What’s worse: so many of these urgent, small fixes are the problems that the product owner pointed out at the iteration demo meeting… wasn’t BDD supposed to fix this problem?
When programmers try to adopt BDD, they often do it as a way to organize what they’re learning about features. They try to use BDD to increase their confidence that they’re building what the product owner has asked for. Along the way, they frequently fall into the trap of treating their examples as a new syntax (Gherkin) for the traditional specifications document. Haven’t we learned by now that we humans generally can’t write precise and complete and unambiguous specifications?! And wasn’t BDD supposed to fix this problem?
It can—or at least it can help a lot—if we remember the first of the four values of Agile software development: let’s value Individuals and Interactions over Processes and Tools. We would also do well to remember the “Three Cs” of user stories: card, conversation, confirmation… many groups who adopt BDD do the first and third of these very well and they hope that this compensates to having no clear strategy for the most important one.
Don’t get me wrong: I have directly experienced these mistakes when trying to “do BDD”. I’ve focused on code, carefully set up the tools, used examples only as regression tests, enforced new specification document standards… I’ve even thought of BDD as “just a different way to write tests”. In all these cases, I got maybe 2% of the value of BDD. I was optimizing before I got any results worth optimizing! I say this to emphasize that we programmers are not stupid because we fall into this trap—it’s perfectly natural to retreat to our comfort zone. We need to help each other see more in order to realize the benefits of BDD, which involves reminding ourselves which problems we intended BDD to help us solve.
Programmers can take full advantage of their programmer-y mind by focusing on one simple technique to start: talking in examples. Doing this well improves the quality of information that they feed into their BDD tool chain. This tends to result in more explicit agreement with stakeholders, more-valuable feedback from shorter cycles, less frustration through rework, and generally more of “building the right thing”. These are the benefits that BDD was supposed to provide.
Great! Sign me up! How do I start? You might already have some intuitive understanding of what it means to “talk in examples”, but there is an art to it. In the next article (will be published on our blog beginning of September), I’ll offer some concrete suggestions on how exactly to start talking in examples, what’s in it for you (and for them!), and how to build an effective BDD practice upon this critical foundation.
J. B. Rainsberger works as an Agile Coach, but actually Agile and actually a Coach. He travels the world (most years) sharing what he’s learned about programming, managing his workload, and designing his lifestyle. He spends much of his professional time helping programmers do better work with less stress, but he also consults with and trains for companies. He helps clients cut through the confusion about Agile to its essence, so that they can realize the benefits that the modern Agile movement has been trying so hard to offer. He offers self-study training and coaches both individuals and teams in whatever they need to perform better. He lives in Atlantic Canada with his wife, Sarah.
J. B. Rainsberger, “Three Steps to a Useful Minimal Feature”. An example of talking in examples. Sure, I was talking with myself, but the examples gave my internal dialog structure that helped me in a variety of ways. It describes one style for writing scenarios/examples that programmers generally find easy to adapt to Gherkin syntax.
Mozaic Works, “BDD in Practice with Liz Keogh”. Adi Bolboaca interviews Liz Keogh, starting with BDD, but moving on to greater topics. Don’t break your brain! If you really need to focus on only talking in examples for now, then put this video into your “Watch Later” list, but do come back to it.
Markus Gärtner, “Shallow Disagreements”. Along with shallow agreements, we might also have shallow disagreements. The first of these describes appearing to agree without confirming that we are using the same words to mean the same things; we might find ourselves appearing to disagree for similar reasons. I find it wise to check!