Behavior-Driven Development: Pros and Cons, Implementation, and Best Practices
This is a guest article by Ron Stefanski from OneHourProfessor
When launching new digital projects, the frequent disconnect between business professionals and engineers often results in tons of squandered time and resources. But, with the right strategy, this black hole can be avoided by improving communication, an effective way to prevent most bottlenecks to project progress.
When business professionals understand the capabilities of the technical team, and the engineers understand what the business truly requires from the software, it results in the creation of software with real business value.
But how do you achieve all this? That’s where behavior-driven development (BDD) comes in.
This article will discuss the nature of behavior-driven development and how it can be used successfully by an organization to assist its technical team in delivering software that fulfills its goals.
What is Behavior-Driven Development (BDD)?
Behavior-driven development can be defined as a way to synthesize and define practices that stem from test-driven development (TDD).
BDD is several things:
- It’s a language used to define the behavior of an application.
- It’s a collaboration tool for product managers, engineers, and testers.
- It’s a system for automatically testing those behaviors.
BDD was created over a decade ago by Dan North, a technology and organizational consultant from London, as a way to clear confusion between developers, testers, and business people. Although it started as a simple modification of test-driven development, BDD is now a full-blown software development methodology.
The BDD approach is often divided into two main parts:
- The first part involves using examples that are written in ubiquitous language as a way to illustrate behaviors or the different ways users interact with the product.
- The second part is the practice of utilizing those examples as a basis for automated tests. In addition to allowing developers to check functionality for the user, it also ensures that the overall system works precisely as defined by the business for the project’s entire lifetime.
Behavior-driven development closes the gap and provides an easier way to collaborate and communicate between different departments so they can manage and deliver software development projects more effectively. BDD ensures that the development projects remain focused on the actual needs of the business while, at the same time, meeting the requirements of the user.
How does it do that?
- By encouraging collaboration across different roles to build a shared understanding of the problem that must be solved.
- By working in small, rapid iterations to increase feedback and enhance the flow of value.
- By producing system documentation that can be automatically checked against the behavior of the system.
This is done by focusing collaborative work on concrete, real-world examples illustrating the way the system is required to behave. Those examples are then used as a guide from concept all the way through to implementation as part of a continuous collaboration process.
What Are the Benefits of BDD?
In BDD, acceptance tests are the starting point for software design. They serve as the basis for communication between stakeholders and the development team.
The biggest challenge software projects face is making certain everyone involved can share a common language. That’s why while building, it may make sense to use a webinar platform to connect all stakeholders to clarify requirements. And therein lies the true benefit of BDD as a powerful communication tool to drive better cooperation between everyone involved – both technical and nontechnical.
With behavior-driven development, everyone on the team can read and write acceptance tests. It’s the developer’s code that automates the tests, but business stakeholders can understand it.
Here are a few other benefits offered by BDD:
- Strong Collaboration. Thanks to the shared language, product owners, developers, and testers all have in-depth visibility of the project’s progression.
- Shorter Learning Curve. Since BDD is explained using very simple language, there’s a much shorter learning curve for everyone involved.
- High Visibility. Being a nontechnical process by nature, behavior-driven development can reach a much wider audience.
- Rapid Iterations. BDD allows you to respond quickly to any and all feedback from your users so you can make improvements to meet their needs.
- BDD Test Suite. Similar to adopting TDD, adopting BDD gives your team confidence in the form of a test suite.
- Eliminate Waste. BDD allows you to clearly communicate requirements so there’s less rework due to misinterpreted requirements and acceptance criteria.
- Focus on User Needs. Satisfied users are good for business and the BDD methodology allows user needs to be met through software development
- Meet Business Objectives. With BDD, each development can be traced back to the actual business objectives.
BDD creates code through the various interactions between users and developers — a process known as “outside-in” development. This means that examples are created that describe software behavior that is evaluated by the user. This is critical to the software development project. Managers clarify responsibilities, mockups help to simulate different system modules before actually writing them, and the use of these tests serves as an opportunity for fast, actionable feedback prior to the development.
Most importantly, behavior-driven development improves the quality of code which helps to reduce costs of variable expenses like maintenance and minimizes project risk.
Also, BDD is a tool that helps all departments clarify the scope of the desired software features so they can get better estimates from development teams.
All in all, BDD practices are a powerful tool to help teams develop better software by demanding prudent specificity of product behaviors using examples in plain language.
What Are the Disadvantages of BDD?
BDD makes it very clear that software development must be done from the interface that is in contact with the end-user (hence the name, outside-in development).
This methodology focuses on the benefits the app will bring to the business. Whether you are yet to implement BDD or if your team is already using TDD and wants to consider BDD, it’s clear to see that the benefits of development are many. But even the best development approaches have their drawbacks, and BDD is no exception.
Although according to its creator, the methodology was designed to address recurring problems in the teaching of test-driven development, it’s clear that behavior-driven development requires familiarity with a wider range of concepts compared to TDD.
Here are a few other common pitfalls of BDD:
- To work in BDD, prior exposure to TDD concepts is required.
- Behavior-driven development is not compatible with the waterfall approach.
- Testers using BDD must have sufficient technical expertise.
- BDD may not be effective if the requirements aren’t meticulously specified.
Keep in mind that using BDD doesn’t require particular program languages or tools. It’s primarily a conceptual approach, and so making it a purely technical practice or even one that is dependent on specific tools means that you’ve missed the point altogether.
Implementing the BDD Approach – Three Practices
Day-to-day BDD activity involves a three-step, iterative process that includes discovery, formulation, and automation (practices that we will take a closer look at below). Over time, these documented examples become assets that help your team to confidently make rapid changes to the system. In this constantly evolving and shared understanding, the code reflects the documentation, which, in turn, reflects everyone’s shared understanding of the problem space.
Step 1: Discovery – What It Could Do
The real objective here is to get valuable, working software for the business. The fastest way to achieve that is by having conversations between all the people involved in the imagining and delivery of the software.
To this end, the first step is to take an upcoming change to the system, known as the user story, and discuss concrete examples of new functionalities to explore. It may make sense to use email marketing tools to survey your users and collect the ideas that they have before you take any action.
This is where everyone involved learns about and agrees to the various details of the expected goals to be achieved.
Test scenarios are written in plain language that everyone can understand, with a detailed description of:
- The actual test
- How to test the application
- The application behavior
As outlined in the benefits above, BDD test cases have the advantage of being written in plain language, ensuring that the details of the app’s behavior are easily understood by all.
For instance, test cases can be written in a simple way using real-time examples of actual requirements as a way to explain the behavior of the system.
Structured conversations, also known as discovery workshops, are used to focus on the system and real-world examples from the perspective of the user. These conversations help to grow the team’s shared understanding of the user’s needs, as well as the scope of what has to be done, and the rules governing the way the system must function.
Step 2: Formulation – What It Should Do
The next step involves documenting those examples in a way that can be automated. You can then check for agreement.
As soon as one valuable example is identified from the discovery sessions, each example can then be formulated as structured documentation. This gives everyone involved a quick way to confirm that they really do have a shared understanding of what needs to be built.
Unlike traditional documentation, BDD uses a median that can be easily read by both computers and humans in order to achieve the following:
- Get feedback from the whole team pertaining to the shared vision of what’s being built
- Automate examples to guide the team’s development of the implementation
This executable specification is written collaboratively to establish a shared language for discussing the system, helping teams to use problem-domain terminology everywhere, including the code.
Step 3: Automation – What It Actually Does
The final step is to implement the behavior described in each documented example, beginning with the automated test that will guide the development of the code. Once the team has its executable specification, it can then be used to guide the development of the implementation. Each example can now be connected to the system individually as a test. This test fails since the behavior it describes hasn’t been implemented yet.
The next step involves developing the implementation code. Lower level examples outlining the behavior of various internal system components are used as a guide wherever necessary. These automated examples serve as guardrails to help teams keep development work on course.
This rapid and repeatable feedback helps to reduce the burden of having to perform manual regression testing which, in turn, helps to free people up to focus on more interesting work, such as exploratory testing.
The diagram below outlines the three practices of discovery, formulation, and automation:
Three practices of behavior-driven development
Source: Cucumber docs
The idea behind this three-step process is to make each of the changes small and iterate rapidly. You can move up a level each time more information is required. Every time a new example is automated and implemented, it means you’ve added something valuable to the system and are therefore ready to respond to feedback.
Best Practices for BDD
Online, you’ll find tons of articles on BDD best practices and anti-patterns. But, with thousands of tips (and sometimes conflicting pieces of advice), how do you which rules are sacred and which are meant to be broken?
To help you in that regard, here are some best practices for BDD that you should keep in mind. We’ve divided the tips into different categories to cover:
- Feature files
- Scenarios and steps
1. Avoid Lengthy Descriptions
All features should have only a sensible and short title and description. Feature descriptions that are long are often boring to read and tend to put off stakeholders. As a general rule, features should be a concise sentence that describes the scope and context.
2. Choose a Single Format for Your Features
Another best feature for behavior-driven development is to decide the types of formats that you use for writing features.
The format you choose should be consistent across all feature files. This makes it easy for anyone who is new to the project to easily understand the features and context.
For instance, you might have the following template:
Feature: [A short line describing the story]
[Optional – Feature description]
Scenario: [A single line describing the scenario]
3. Keep the Background Short
Whenever possible, continue to use a background for shared steps that are required for each scenario in your feature file. The background gets rid of many of the repetitive steps and its proper use can help you avoid duplication in feature files. Keep your background short, ideally no longer than four lines. It should act as a prerequisite for every scenario in the future file.
Users tend not to think about the background when reading scenarios within the feature files so make sure you use something that’s very generic, such as Given the user has logged in.
4. Avoid Using Technical Language in the Background
Make sure you avoid using technical stuff (language or actions) during the background step. For instance, you shouldn’t have a background step for things such as starting/stopping Apache, clearing the cache, truncating database, etc. since users don’t really care about these things.
You can implement any of the technical actions you need to do in the before hook or step definitions instead.
5. Don’t Tag the Background
Never tag the background, only the scenarios, and features. Also, never use the background for feature files that contain just one scenario. This doesn’t make sense since you can include the details directly in the GIVEN step.
Another thing to avoid is the use of both before hook and background at the same time. There are times when there can be duplication of context when there’s a background within the feature file, as well as a before hook within the code. So make sure you use either one or the other, but never both.
6. Consider Scenario or Scenario Outline
A tool like Gherkin provides a way to deal with single examples using a “scenario,” as well as the means to deal with multiple examples using a “scenario outline.”
Decide how many examples you’re going to think of for each particular scenario. If the scenario can only have one example, then you can use “scenario.”
In any other instance, you can use “scenario outline” to cover multiple examples. You can use the table for this. And proper use of scenario outlines will also help to make your scenarios a lot more readable and maintainable, as well as prevent you from duplicating steps.
7. Keep Scenarios Short
Another best practice for BDD is to hide implementation details and avoid using technical details in order to keep scenarios short. Long and descriptive scenarios that include lots of “AND” or “BUT” steps become brittle and less readable.
So while your steps should not include the implementation details, they should have enough description for the context of the scenario to be clear.
8. Use the Given-When-Then Formula in the Right Order
When writing scenarios, use the right sequence for the GIVEN-WHEN-THEN steps (with the proper use of “AND,” and “BUT”).
This style of writing makes it easy for anyone to understand since it doesn’t contain any implementation details. It also highlights the reasons why a specific feature is important for any given persona.
Always start the scenario using the GIVEN step (do this even if you used it in the background section).
Given [some context]
When [some action or event occurs]
Then [some outcome occurs]
The proper sequence of this formula is important because scenarios become a lot less readable when the order of GIVEN-WHEN-THEN is missed.
9. Cover Happy and Non-Happy Paths
Your scenarios need to cover not only the happy path where the user has a straightforward journey but also the non-happy paths that cover different edge cases surrounding the happy path.
This includes invalid inputs, among other things. It’s important to cover both paths and ensure that scenarios that are implemented have business values (ROI).
10. Points To Consider for “Tags”
Tagging lets you organize features and scenarios properly in your BDD project. If your feature files span across different directories, then you can use tags to help filter specific scenarios of features.
For instance, say you have a set of scenarios for Gmail, you can then use the “@mail” tag to mark those scenarios. That way, you can easily search for the @mail tag.
Here are a few more tips concerning tags:
- Use Relevant Tag Names: For instance, you can use @daily, @hourly, or @nightly for frequency of execution. Likewise, progress can be labeled using @wip, @todo, @implemented, or @blocked, and so on.
- Tagging Features Smartly: You can tag individual scenarios, but tagging an entire feature may be useful in some instances. For instance, you might tag a feature using a story number (e.g. @Jira-story #PROJ-43) in JIRA or any other bug tracking system.
- Avoid Unnecessary Tag Use: Don’t tag a scenario using the same tag that you used for a feature. If you’ve tagged an entire feature, then the scenarios inside the feature automatically inherit the tag. So you should never use a lot of unnecessary tags in your project or the result will be overcomplication of your feature files.
Remember: Practice Makes Perfect
When dealing with behavior-driven development, there are a ton of rules that you can use as guiding principles, but only practice will allow you to become an expert in this smart approach in agile methodology.
Use this guide as your resource to learn everything you need to know about BDD to drive collaboration among customer representatives, quality assurance testers, and developers in your next software project.
Did this guide effectively answer all your questions about behavior-driven development? Are there any areas of BDD you’d like to learn more about? Share your thoughts in the comments below!
Ron Stefanski is a college professor turned online business owner. He’s helped hundreds of thousands of people create and market their own online business. You can learn more about him by visiting OneHourProfessor.com. You can also connect with him on YouTube or Linkedin.
Want to write an article for our blog? Read our requirements and guidelines to become a contributor.