Want Better Collaboration on Development Projects? Try BDD


If you’ve engaged in the software development trade at any level, you’ve probably seen countless examples of x-driven development paradigms and practices.

Go through a couple of basic articles, and this is the sort of word salad you’ll definitely run into: ATDD, BDD, CDD, DDD, FDD, MDD, TDD, YOLODD

These are different answers to the age-old question of how to design, develop, test, and maintain software.

In the scope of this blog post, we’ll focus on BDD or behavior-driven development.

As is the case with most things in software development, it’s not a silver bullet that will fit every team and project.

However, speaking from experience both in software testing and product ownership, I believe BDD has the potential to level the playing field and help team members and business people speak the same language.

Development teams behaving badly

Do you feel like software development teams often behave like neglected children throwing tantrums?

Then you’ve probably heard some of the old tropes a thousand times:

  • We’re agile, we don’t need no documentation.
  • The testers were supposed to test that.
  • We don’t have time to automate x.
  • We can cover the edge cases later.
  • Users don’t even care about that feature.
  • Wasn’t that out of scope?
  • It works on my machine.

When your development process is driven by excuses and compromises, you cannot handle change.

That’s why some software projects inevitably slow down and end up in spaghetti code and rogue bugs after a couple of months or years.

Why does that happen? More often than not, the problem lies in the lack of collaboration and mutual understanding, not a lack of technical expertise. BDD can help with that.

So, what’s BDD really about?

Let’s start with the good old user story, the cornerstone of software specification nowadays.

If you look at BDD from a surface-level perspective, most people think it is just about using Gherkin to specify user stories.

You start with specifying some acceptance criteria using Gherkin and store them into .feature files.

Feature: Blog posts

  Scenario: Viewing recent blog posts
     When the visitor navigates to the Blog page
     Then the visitor sees the header is "Capsized Eight"

The next step is to parse those steps and implement them using their favorite test automation framework.

SpecFlow, Cucumber, JBehave, or FitNesse might ring a bell already. Since we appreciate the simplicity of Python, our first weapon of choice for this exercise would be Behave with a bit of Selenium WebDriver thrown in for good measure.

from behave import *

@when(’the visitor navigates to the Blog page’)
def step_impl(context):

@then(’the visitor sees the header is "{header}"’)
def step_impl(context, header):
    actual_header = context.browser.find_element_by_css_selector("h1.__title.__title--large")
    assert(actual_header.text == header)

Easy, right? Seeing as test cases are usually related, you will be able to reuse some individual steps across your entire test suite.

The problem is people usually spend most of their time discussing tools, which is of secondary importance here.

The way you implement BDD into your software development process is key to transforming your way of working and breaking down the old silos.

Three ways in which BDD helps with your development process

1. It encourages communication and collaboration

In any situation and context, communication is indispensable for success. A user story should not be a set of rigid criteria that are handed over to the development team like the Ten Commandments. A user story should be no more than an invitation to a discussion.

There is a very nice collaborative principle that can be employed around BDD called the Three Amigos. The Three Amigos usually consist of:

  • Product owner, who understands the business needs and what problem we are trying to solve
  • Developer, who understands the technical perspective and how the problem can be solved
  • Tester, who represents the user and understands the strengths and weaknesses of the system

These three in collaboration should come to an agreement on how to specify, develop, and test a specific feature to max out their chance of success. They should do it often and for every backlog work item that might be picked up for the sprint.

The discussion is usually structured and the outcome of their discussion can then be consistently formalized using a DSL like Gherkin, which is both human and machine-readable. The obvious added benefit is that any interested party can understand Gherkin, but not everyone has the ability to dig through Swagger docs and code snippets.

2. It makes the user a first-class citizen

Too often, we find ourselves thinking about how to structure our API or how a particular feature should be presented to the user. While those are completely valid concerns, we often jump the gun and lose focus on the end goal.

By practicing BDD, you might end up dismissing parts of the feature because you realize they might be nonsensical and wasteful, or add others because you realize there is a certain use case that only the tester had in mind.

That happens because you tend to naturally:

  • Break down stories into digestible chunks that bring actual value to the user or value to the business
  • Talk about real use cases and examples instead of the lorem ipsums of the world
  • Think of the high-level implications on the user experience
  • Think of narratives instead o raw requirements or tests

3. It turns tests and documentation into living things

In an ineffective system, each potential change in the application usually results in changing the specs, changing the test documentation, and changing the automation code.

Think of how badly the costs scale when you are doing the same thing three times over. Why not do all three in one fell swoop? Well, that’s where BDD can help.

When practicing BDD, you essentially:

  • Get one consistently structured source of truth everyone can understand
  • Enable mutual understanding of which tests are being executed
  • Ensure test maintenance because changes in feature docs need to be reflected in the test code
  • Enable re-usability because once you’ve implemented a step, you can plug it in anywhere
  • Do test-first automation instead of the old we’ll do it last if there’s time principle

Disrupt your old routines

Regardless of whether I’ve left you intrigued or completely skeptical, I would encourage you (or dare you?) to disrupt your old routines and do a small-scale BDD experiment, it might illuminate some weak points you are currently unaware of.

If you do, feel free to share your experiences below!