Skip to content

behavior-driven development (BDD)

Behavior-driven development, or BDD, is a software development practice in which a team agrees on what a feature should do by writing concrete examples in plain language. Those examples then live alongside the code as executable documentation.

The practice grew out of code testing in the early 2000s, when Daniel Terhorst-North found that newcomers to test-driven development kept getting stuck on the word “test.” He started swapping “test” for “behavior” in his teaching. In 2003, he began shipping a Java framework called JBehave to back the new vocabulary up with running code. He coined the term behavior-driven development in a 2006 Better Software article titled “Introducing BDD.”

How It Shows Up in Practice

A Python team adopting BDD runs three loops, not one, that take a user story from conversation to an executable test:

Top-down: a User story flows through three colored loops, teal Discovery, lavender Formulation, tan Automation, each paired with an artifact via a dashed refine arrow, ending at an Executable test.
Three loops carry a user story from conversation to an executable test.

Cucumber names them Discovery, Formulation, and Automation, and each loop owns a different meeting, artifact, and toolchain:

  • Discovery happens in a “three amigos” session where a product person, a developer, and a tester walk through real examples for an upcoming user story.
  • Formulation turns those examples into a .feature file written in Gherkin, a plain-language format any of the three can read.
  • Automation binds each line of the feature file to a Python function so the document doubles as an executable acceptance test.

The lingua franca of the formulation step is the Given / When / Then scenario template. A feature file for a checkout flow looks like this:

Feature: Discount codes

  Scenario: A valid code reduces the cart total
    Given a cart with one item priced 100
    When the customer applies code "SAVE10"
    Then the cart total is 90

The two BDD frameworks in common use in Python are behave and pytest-bdd. Both bind each Gherkin step to a Python function with a decorator, turning the plain-language steps above into executable tests.

Running behave or pytest from the project root then executes every scenario and prints a green or red line per Given / When / Then, the way pytest or unittest reports plain unit-test results.

BDD vs. TDD

BDD and TDD answer different questions. TDD asks the developer “what should this function do?” and the answer is a unit test written in code. BDD asks the whole team “what should this feature do?” and the answer is a scenario written in shared business language that is then automated.

A BDD scenario typically covers more of the system than a TDD test, and it lives in version control next to the user story rather than next to the unit it describes.

In practice, most teams use both. Outer-loop BDD scenarios drive each user story to completion. Inner-loop TDD then drives the small design choices inside each step’s implementation. Pick the next entry by which question you are trying to answer.

Tutorial

Getting Started With Testing in Python

Learn Python testing in depth by writing unit and integration tests, measuring performance, and uncovering security issues. Find bugs before your users do!

intermediate best-practices testing

For additional information on related topics, take a look at the following resources:


By Martin Breuss • Updated June 5, 2026