Behavior Driven Development
By: Albert Starreveld
Tags: Continuous Delivery, Agile, Continuous Integration, Bdd, Shiftleft

Applications automate processes. Somebody explains the process and someone else builds the application. Seems straight forward, right? Or is it? Perhaps this video changes your mind:

Describing a task as simple as making a sandwich seems simple, but as you can see, plenty of things that can go wrong. Ironically, many software development projects have a lot in common with this video.

It’s impossible to describe a process perfectly. As you can see, assumptions can have a big impact on the final product. It’s not just the person who writes the instructions who’s making the assumptions, the person who’s reading them does too. They don’t do it deliberately either, nor are they aware they’re doing it. And who knows what they’ll assume?

Only by improving the instructions iteratively, eventually, the peanut-butter family get a shared understanding. Too bad so much peanut butter and jelly got wasted in the process…

Building software, unline making peanut butter jelly sandwiches, is expensive. Not every company can afford too much waste. Starting to work on a project, knowing the stakeholder and the development team understand each other, makes for a much higher chance of getting the right end-result. As a result, there’s less waste and the time to market is shorter.

What is BDD?

Behavior Driven Development is a communication framework. It’s a way of communicating about a product on a holistic level before it’s been built. It’s a framework that helps create a shared understanding.

Behavior Driven Development is a software development practice that shifts the testing process to the left. First, the stakeholders and the development team describe the correct behavior of the software. It’s written down in a testable format that allows the team to start building automated tests before writing any code. These tests guide them through the process of writing the code and can be executed at ane time, automatically. As a result, an automated regression set gets created which allows the team to automatically test everything they’ve built in the past.

Behavior Driven Development goes hand in hand with the scrum/agile methodology. Behavior Driven Development can be used in the refinement to discuss the acceptance criteria of a user story.

BDD makes it easy to release fast and often. Every user story results in both new code and new tests. As a result, the integrity of the software can easily be validated by running automated tests.

Stories are discussed by using a method called example mapping. It allows the team to discover the acceptance criteria of a user story by naming example use cases as follows:

Step 1.) Visualize it

In this example, we’re building a calculator. Dividing numbers is a feature of the calculator and we have a user story to build it.

It’s an acceptance criterion that the outcome of a sum must be visible. Therefore, the calculator needs a display to display the answer to a math problem. Requiring a display, much like making a peanut butter jelly sandwich, seems pretty obvious. Still, there’s plenty of room for assumptions in this acceptance criterion.

Let’s make the story visible by writing the acceptance criteria on blue post-its, and add example math problems to these acceptance criteria:

These examples are simple. They’re the “happy flow”. But will edge cases meet the acceptance criteria too? Dividing 1 by 3, for example, results in a number too long to display on any screen and dividing by 0 won’t have a result at all:

Red post-its contain examples that are likely to occur but can’t meet the acceptance criterion. Don’t spend too much time discussing them. If there’s an obvious solution to the problem, turn that into a new acceptance criterion. Otherwise, go back to the stakeholders and ask them how to deal with these edge cases.

Assume we limit the characters on the display. A new acceptance criterion appears:

“Results longer than 15 characters will be truncated. “

How to deal with edge cases isn’t always obvious. Don’t waste time discussing them for too long. If the answer isn’t obvious that’s something for the product owner to figure out. Complete the example map when the product owner figured out what the missing acceptance criteria are. Keep adding examples to the new acceptance criteria that are clear.

Step 2.) Add examples

Add examples to challenge the new criteria too, because it might reveal even more scenario’s we haven’t thought of. In some cases, this process keeps revealing new acceptance criteria, endlessly. That shows a story is too big. Cut the story into smaller stories with a smaller scope.

In this example, another problem appears: What if not the output, but the input is too long? If it’s longer than 15 characters, the result cannot be displayed:

Another acceptance criterion appears:

After figuring out all examples the complete example map looks like this:

Step 3.) Convert the examples to specifications

Example mapping is a great tool to explore the acceptance criteria of a user story. But they are not an efficient way to document the requirements of a story. They often lead to questions (that were probably discussed in the refinement meeting) later on.

Write the examples and acceptance criteria down in a structured way. Use scenarios to describe the behavior of the application. Every acceptance criterion should result in at least one scenario.

Start by specifying the starting conditions of a scenario. Then, describe what the application does, and then describe what the expected outcome should be:

Feature: Dividing numbers

As a math idiot

I want to have my computer divide numbers for me

So that I can’t make any mistakes Scenario Outline: Result of a calculation should be displayed on the screen

Given a number (<Number>)

And another number (<Number to divide by>)

When these numbers are divided by each other

Then the calculator shows the outcome of the calculation

Examples:

|Number| Number to divide by |

| 2 _____| 1 _______________ |

| 2 _____| -1 _______________| Scenario: Results longer than 15 characters are truncated — thirds

Given a number (1)

And another number that’s three times that number (3)

When these numbers are divided by each other

Then the calculator shows 15 digits, followed by “…” Scenario: Results longer than 15 characters are truncated — long input

Given a number (2,9999999999999999999999999)

And another number (2)

When these numbers are divided by each other

Then the calculator shows 15 digits, followed by “…”

And so on…

This way of writing scenarios is also known as the Gherkin language or Specification by Example.

Use these specifications to communicate with the stakeholders. The specifications should be understandable to them so they can use it to validate the behavior of the application before it’s been built. That way, bugs are identified early in the process.

Step 4.) Write an automated test

A key benefit of BDD is that assumptions are made visible to the stakeholders before the product has been built. BDD tools like Example Mapping and Specification by Example result in explicit, clear, testable specifications.

It has another benefit. The explicitness of the specifications makes it easy to turn them into automated tests. Several BDD tools make it possible to do so. For example:

Cucumber (a Java BDD-framework)

SpecFlow (a C# BDD-framework)

MSpec (a C# BDD-framework)

These frameworks allow the development team to approach the process of implementing a feature TDD-style: the developer builds a failing test first. Then he starts writing code until the test passes. As a result, you’ll end up with a fast test-set that has high coverage. This is what the development process looks like:

Automate the BDD specification first. Use tools like Cucumber/Specflow to do so. Use RestAssured and Selenium to allow the specification to invoke the application. To make the application work, the developer will probably make changes in several places. Perhaps he’ll make a class to store things in a database and another class to make calculations, and so forth. Build those using the TDD cycle. Make a unit test. Make it pass. Refactor the code if need be. Considering the entire application is the subject under test in a BDD test (or at least a big part of it), implementing one class will most likely not make the test pass. Keep repeating the TDD cycle until everything is in place and the BDD test succeeds.

Summary

The hardest part of building software is making sure you’re building it right. Communication is key. BDD is a communication framework. Eliminate waste and shorten the time to market by making assumptions visible early in the development process.

BDD and TDD are much alike. The developer starts by implementing a failing test and keeps writing code until the test passes.

Use an example mapping to visualize and discuss the behavior of the application. Write the behavior and the examples down using the Gherkin language. These specifications are the functional documentation of the system. It allows the stakeholders to test the software before it’s been built.

Validating assumptions like using this methodology make for a much smoother development process.