TestingFeb 11, 202513 min read

What is Behavior-Driven Development (BDD)?

Jacob Schmitt

Senior Technical Content Marketing Manager

A vertical line spirals into increasingly complex shapes until it becomes a starburst.

Behavior-Driven Development (BDD) is a software development methodology in which applications are built to match the behaviors a user would expect from the software. An evolution of Test-Driven Development (TDD), BDD gathers user stories about how users expect applications to behave, then creates software tests to validate that their applications match this behavior.

The BDD methodology utilizes specific language and naming conventions. Software tests use domain-specific language and expressive naming conventions to describe system behavior. These naming conventions help to bridge the gap between technical and non-technical project stakeholders by making it easier to understand the purpose of the code.

What is Behavior-Driven Development (BDD)?

Dan North introduced the principles of BDD in his 2006 blog post entitled Introducing BDD. Dan describes how his experiences with Agile practices and TDD frequently led to the same stumbling blocks.

Dan found that by writing expressive names for his software tests, it became easier to understand the behavior of the system simply by reading the code. Rather than getting lost in the weeds of ensuring an application could pass tests that might have arbitrary names unrelated to their role in the bigger picture, Dan established naming conventions that express the expected behavior in the form of test and method names.

Ultimately he discarded the word “test” from his code and re-oriented his approach to focus on behavior. This provided a new way to conceptualize the development process, starting from an expected behavior documented in a user story and writing code to test if the system exhibited that behavior.

By extending the framework of TDD to emphasize behavior and incorporate expressive test names, BDD makes it easier to translate expectations into code. BDD emphasizes several core components:

  • Focus on behavior: BDD writes code to match users’ expectations of system behavior. Development prioritizes the expectations communicated in user stories to better understand what users want from the application.
  • Shared language: BDD uses a shared language that all stakeholders can understand. It enforces naming conventions to narrow the gap between technical and non-technical stakeholders, facilitating more effective communication throughout the development lifecycle.
  • Test automation: Application behavior is tested programmatically using automated testing. Applications must pass these tests to verify that they perform the behaviors as expected. This process is facilitated through BDD testing tools, such as Cucumber and behave.
  • Living documentation: Collecting user stories, writing feature files, utilizing shared language, and generating reports from test automation creates numerous BDD artifacts that serve as living documentation generated organically during development.
  • Iterative development: BDD emphasizes making small incremental changes to the system. Each change is validated through testing to minimize risk and ensure the application aligns with expected behavior.

Key components of BDD

At the core of BDD is a concept familiar to Agile software development practices: user stories.

User stories are short descriptions of software behavior from the perspective of the end-user. A user story describes who the user is, what they want from the application, and why they want it.

A user story offers developers a clear window into what functionality (in other words, what behavior) real users expect from an application. A good user story is very brief, typically 15 words or less, and answers the questions of who, what, and why to describe a specific requirement.

By creating a pipeline that turns user stories into working code, BDD enhances collaboration between different teams. In BDD, all changes and new features originate as user stories that explore specific scenarios describing what behaviors users expect from the application. These user stories can originate from any stakeholder, whether they are a business leader, a customer, a Quality Assurance (QA) tester, or anyone else with a stake in the project.

The Given-When-Then format

One of the major advantages of BDD is that it defines a ubiquitous language for users, stakeholders, and software developers alike. This language originates in the user stories and defines the behaviors and naming conventions of the code.

The core of this is the Given-When-Then format for describing scenarios. This format breaks down a user story scenario into a reusable template. In its simplest form, it looks like this:

Given Some initial conditions,
When Something happens,
Then I expect this behavior.

Through the Given-When-Then format, users can quickly express what they want from an application, and developers have a shortcut to understanding what behaviors the system needs to exhibit to match the user’s requirements.

Consider an example from a banking app:

Given I am a user who wants to be notified when their balance goes down,
When A transaction occurs debiting the account,
Then Send a push notification indicating the balance has decreased.

Or another banking app example:

Given A customer’s account is in overdraft,
When The user initiates a transfer,
Then Deny the transfer until the overdraft is resolved.

BDD tools and frameworks

Several tools and frameworks facilitate developers utilizing the BDD methodology.

One key tool for communicating behaviors into code is Gherkin. Gherkin uses the Given-When-Then format to write human-readable descriptions of software behavior in a structured format. These scenarios can be executed by BDD testing tools such as Cucumber and behave, which use the Gherkin syntax as a basis for automated testing.

These frameworks facilitate the process of generating tests to validate behaviors described in user stories. With BDD being an inherently test-driven methodology, tools like Cucumber simplify the process of writing software tests by ensuring the right behaviors are being tested for. Utilizing expressive test names and enforcing BDD’s naming conventions provides visibility into the parity between behavior requirements and actual implementation.

Gherkin scripts are saved in a “feature file” format. Feature files are stored in the same repositories as the project’s code, making it easy to use them as the basis for integration testing. The feature files provide living documentation that can be maintained and added to throughout the project’s lifecycle.

Benefits of using BDD

Some common benefits of implementing BDD include:

  • Improved communication and collaboration: Fostering a collaborative environment where user stories are a source of truth for development and utilizing a shared language all stakeholders can understand creates opportunities for collaboration.
  • Enhanced understanding of requirements: With expectations communicated using standardized templates such as the Given-When-Then format, project requirements remain clear and well-articulated throughout development cycles.
  • Better alignment between business goals and technical implementation: By contextualizing software within the domain-specific language and requirements of its stakeholders, teams are able to translate business goals into practical code more effectively.
  • Increased test coverage and code quality: Validating system behavior through automated testing keeps code coverage high and helps to enforce best practices for improving code quality.

BDD process

The BDD process can be broken down into three primary phases that occur within a repeatable cycle.

Discovery phase

In the discovery phase, the primary goal is to understand the project’s requirements and to document them effectively. The discovery phase involves gathering information from stakeholders and generating user stories.

During the discovery phase, teams should prioritize effective communication and take steps to facilitate conversations and collaboration. This is a great time for hosting workshops and structured events that invite stakeholders to offer their input on the project and what they’d like to see from the application.

A productive discovery phase identifies specific scenarios to refine in the next phase.

Formulation

In the formulation phase, the scenarios from the discovery phase are translated into testable requirements. This is where the formal Given-When-Then format comes into play. Scenarios can be written in a structured format, such as Gherkin, to prepare them for the next phase.

Automation

In the automation phase, developers create automated tests to validate that the system is behaving as described by the requirements determined in the formulation phase.

In the case of adding a new feature, these initial tests will fail, since the application does not support that capability. Developers can then begin working to modify the application until it is capable of passing the test.

Execution and reporting

Once automated tests are written, they can be executed to generate reports. Tests can be run automatically each time the application is built, ensuring that the application always meets the requirements.

Reports provide ongoing insight into system behavior. They can also be useful for creating documentation of the application and the project itself.

Iteration and improvement

BDD prescribes an iterative process of adding incremental improvements. The phases described above are repeated in each development cycle.

As the application improves its functionality, stakeholders continue to interact with the application and generate user stories about their expectations. This provides fresh input for the BDD process, giving developers a continuous cycle to refer back to for enhancing the application throughout its lifecycle.

Integrating BDD into the development workflow

The BDD methodology aligns well with Agile practices. BDD encourages inter-team collaboration and communication while prioritizing iterative development.

Techniques familiar to Agile, such as Three Amigos meetings, translate perfectly to BDD. In a Three Amigos meeting, business analysts, software developers, and QA testers come together to ensure the software meets business requirements and expectations. These types of collaborations are ideal for the Discovery phase of BDD.

BDD’s shared language helps to ensure that inter-team communications are more effective. The natural language approach of the Given-When-Then model allows the Three Amigos to provide an effective review regardless of their technical background or familiarity with programming.

BDD methodologies can be applied to address the user stories in a Scrum backlog and used to set priorities during a sprint. Similarly, BDD helps set priorities when working with Kanban. The clear path from user story to testing to implementation provides a granular approach to determining project goals and creating clear expectations for deliverables.

Role of BDD in Continuous Integration and Continuous Deployment (CI/CD)

The tools and best practices from Continuous Integration and Continuous Deployment (CI/CD) are instrumental for performing BDD efficiently.
CI/CD automates merging, building, and testing new code. With BDD being an inherently test-driven methodology that emphasizes incremental changes, CI/CD directly facilitates the needs of BDD teams.

A CI/CD pipeline ensures that new code is tested during every build and is always ready to deploy. Continuous integration (CI) creates ample opportunities for developer collaboration, allowing individual developers to merge their changes into larger code bases seamlessly.

In a CI/CD workflow, BDD tests can be executed automatically at various stages of the pipeline. During the build stage, the pipeline runs unit and component-level BDD tests to validate individual functions. In the test stage, integration and acceptance tests ensure that features align with user expectations. Advanced pipelines may incorporate parallel execution of BDD tests across multiple environments to optimize speed.

Failed BDD scenarios trigger automatic feedback loops, alerting developers to fix behavioral mismatches before merging changes. By embedding BDD in CI/CD, teams can enforce test-driven collaboration, reduce regressions, and align software development with business goals, ultimately accelerating high-quality releases.

BDD vs TDD vs ATDD

BDD is one of many different approaches to development. Let’s compare BDD with two other closely related development methodologies.

  • Test-Driven Development (TDD): As the precursor of BDD, the methods of TDD overlap significantly with BDD. But where BDD focuses on system behavior, TDD is more concerned with code functionality. The primary tool in the TDD arsenal is the unit test. The TDD approach emphasizes writing tests before writing code, and ensuring code can pass those tests. Both TDD and BDD rely on testing as a pillar of the approach, but TDD zeroes in on the nuances of ensuring individual pieces of code can pass unit tests, rather than zooming out on the big picture of user and system behavior.
  • Acceptance Test-Driven Development (ATDD): Though very similar to both BDD and TDD, ATDD adds the concept of acceptance criteria into the mix. Acceptance criteria are the testable requirements an application must meet to be considered complete by stakeholders. While in many ways similar to the behavior requirements of BDD, acceptance criteria emphasize stakeholder expectations and ATDD stakeholders require a higher level of technical experience to define acceptance criteria.

Challenges in implementing BDD

The foundation of effective BDD is a culture of collaboration and communication. Teams that struggle to communicate will find difficulties in defining (and agreeing upon) project requirements. Insufficient training in BDD methods and lack of preparation can exacerbate this issue.

Test automation can present a technical challenge for engineers working with BDD. Some applications, or behavior scenarios, may be difficult to test effectively. Validating complex behavior requirements programmatically can be a challenge on multiple fronts, from engineering to documentation to communicating the requirements.

To be effective, BDD requires living documentation which must be updated and added to throughout the development lifecycle. This can create additional overhead in maintaining Gherkin feature files, which need to be regularly reviewed and updated.

Key metrics to assess BDD performance

The primary goal of BDD is to create parity between expectations and application behavior. However, it can be tricky to measure such an abstract goal empirically. Instead, we can look at some different metrics to quantify the performance of BDD:

  • Test coverage: Measures how effectively software tests examine system behavior. Effective BDD practices necessitate high test coverage. All behaviors expressed as user stories should be validated through testing.
  • Defect rates: The number of bugs, errors, and other defects in the application. High defect rates can be a symptom of collaboration and communication issues, or challenges in translating user stories to system behavior during implementation.
  • User story completion rate: A user story is considered complete once the corresponding code has been developed, tested, documented, and deployed. Low user story completion rates indicate poor throughput on the BDD process.
  • Stakeholder satisfaction: With all changes in BDD originating from stakeholder expectations, it is vital to engage with stakeholders through surveys and other means to gauge their satisfaction regarding how closely the application matches expectations.

Conclusion

BDD provides a structured methodology that enables organizations to translate business requirements into functional applications that meet stakeholder’s expectations. By prioritizing user stories as the driving force for defining requirements, and ensuring functionality is validated through automated testing, BDD offers a powerful framework that aligns the needs of stakeholders with the goals of developers.

This iterative development process, where new code is merged into an existing code base and subjected to automated testing, is a strong foundation for any development project. BDD is complemented by practices like CI/CD, which automate repetitive tasks such as integrating, building, and testing code. CI/CD tooling offers automation and helps to enforce best practices, ensuring that BDD practitioners have the tools and data they need to achieve their goals.

Sign up for a free CircleCI account to set your next BDD project up for success with an efficient CI/CD pipeline.

Copy to clipboard