Toward BDD — a Vocabulary Revolution That Focused Testing on Behaviour

Dan North, while practicing and coaching TDD at ThoughtWorks, realized that the confusion beginners kept running into had its roots in the word 'test' itself. Starting with JBehave in 2003 and systematized in a 2006 paper, BDD spread through RSpec and Cucumber/Gherkin into a culture of writing 'executable specifications.' We trace how the Given-When-Then vocabulary took hold across the industry, and weigh its gains and costs.

testinghistorybdddan-northrspeccucumbergherkin

Behaviour-driven development (BDD) grew out of the practice of test-driven development (TDD) — yet it is a methodology that only resembles TDD on the surface.

Its creator, Dan North (formally Daniel Terhorst-North), kept running into the same questions while teaching TDD: “How far should I test?” “Should this even be called a test?” “What should I test first?” North came to realize these weren’t technical problems at all — they were vocabulary confusion caused by the word “test” itself. From that realization came a new practice that put “behaviour,” not “test,” at the center of its vocabulary. That practice is BDD. It would go on to take concrete shape through three pivotal tools — JBehave, RSpec, and Cucumber — giving rise to a culture of writing “executable specifications” in the structured natural language of Gherkin and Given-When-Then.

The Confusion Bred by TDD’s Word “Test”

In the early 2000s, North was working at ThoughtWorks, practicing and coaching TDD. What he kept observing was a fundamental confusion that TDD beginners shared.

  • Uncertainty over whether to name test methods testXxx, or what exactly they were supposed to be testing
  • A blurry boundary between “unit test” and “acceptance test”
  • Being told to write “test-first,” with no idea what to verify against a feature that doesn’t exist yet
  • As tests piled up, they started to look like “tests for the sake of tests,” losing their connection to business value

North concluded that the root of these problems wasn’t technical — it was linguistic. The word “test” evokes “verification,” and that obscures the design and specification side of the question: what are we actually trying to build? So North proposed replacing test code naming with should~ instead of test~. This shifts the focus from “verification” to “describing the expected behaviour.”

The Birth of JBehave (2003)

At the end of 2003, North began writing JBehave, a JUnit alternative that dropped the vocabulary of “testing” entirely. JBehave aimed to rewrite the grammar of Java unit testing as “behaviour specification,” and it developed through 2004. Liz Keogh and Chris Matts, both of whom would go on to shape BDD further, were involved from this early stage.

At the end of 2004, while North was explaining his “behaviour-centered vocabulary” to Chris Matts, Matts remarked, “Isn’t that just analysis?” — an episode now remembered as the turning point at which BDD expanded from a unit-testing technique into a technique for requirements analysis and acceptance criteria. In that same current, Matts devised Feature Injection, a method for surfacing features starting from business value.

“Introducing Behaviour-Driven Development” (2006)

In March 2006, North published a paper systematically introducing BDD, “Introducing Behaviour-Driven Development,” in the trade publication Better Software. The paper laid out BDD as follows:

TDD terminology BDD’s reframing
Writing a test Specifying behaviour
Test method name testXxx A sentence of the form should~ / it~
Blurry line between unit and acceptance tests Clear separation between “developer-facing behaviour” and “business-facing behaviour”
Tests become documentation (a byproduct) Written as a specification from the start (a primary artifact)

The paper also introduced Given-When-Then as a template for writing acceptance criteria. This three-part structure — “Given” (preconditions), “When” (an action or event), and “Then” (expected outcome) — was heavily influenced by the ubiquitous language that Eric Evans advocated in domain-driven design (DDD): the idea that developers and domain experts should share a common vocabulary.

The Birth and Growth of RSpec

Where JBehave had been an experiment in the Java world, it was RSpec that let BDD’s ideas truly flourish in Ruby.

  • 2005 — Steven Baker started RSpec as an experiment. Dave Astels and Aslak Hellesøy joined as early contributors
  • Summer 2006 — David Chelimsky joined the project, later taking over its leadership
  • May 2007 — RSpec 1.0 was released, establishing the syntax of a describe block for the subject and an it block for the expected behaviour
describe Order do
  it "is invalid when the total is negative" do
    order = Order.new(total: -10)
    expect(order).not_to be_valid
  end
end

This describe/it/expect syntax delivered the experience of writing a “spec” rather than a “test case,” embodying BDD’s vocabulary at the code level. In 2009, Chelimsky and Astels, together with co-authors Bryan Helmkamp, Dan North, Zach Dennis, and Aslak Hellesøy, published The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends, codifying the practical knowledge of BDD.

The Birth of Cucumber and Gherkin

Aslak Hellesøy, an early RSpec contributor, went on to build Cucumber, a tool for writing acceptance criteria in something close to natural language and running them directly as executable tests. Cucumber started out for Ruby, later expanding to many languages (Cucumber-JVM, SpecFlow for .NET, behave for Python, and others).

At Cucumber’s core is the Gherkin notation. Gherkin formalizes the Given-When-Then structure as natural-language-like text that even business stakeholders can read and write.

Feature: Applying a discount coupon

  Scenario: A valid coupon is discounted
    Given the cart total is 3000 yen
    And I have a valid 10% discount coupon
    When I apply the coupon
    Then the total becomes 2700 yen

This scenario is wired directly to code called “step definitions” and executed as an automated test. In theory, this let a specification readable by the business side and the actually running test code stay in sync.

BDD Frameworks Spread Across Languages

The Cucumber/Gherkin model spread rapidly beyond Ruby into other language ecosystems.

Language / environment Tools Notes
Ruby Cucumber, RSpec The originals; both Gherkin and RSpec-style syntax coexist
Java / JVM Cucumber-JVM, JBehave JBehave is the wellspring North himself created
.NET SpecFlow Runs Gherkin on .NET; its successor is Reqnroll
Python behave, pytest-bdd Some tools integrate Gherkin-style .feature files with pytest
JavaScript Cucumber.js, jest-cucumber It’s also common to feed Gherkin scenarios into Jest’s describe/it

All of these are built on the shared vocabulary of “Given-When-Then” and Gherkin-style notation, showing that BDD took hold as a common language for writing tests — not merely a fad within one language.

Specification by Example and Example Mapping

As BDD practice spread, a movement also arose to systematize the discovery process itself — how do you collaboratively surface Given-When-Then scenarios? In 2011, Gojko Adzic published Specification by Example: How Successful Teams Deliver the Right Software, based on roughly fifty project case studies, codifying the practical knowledge of “specification through concrete examples” that sits close to BDD (the book won a 2012 Jolt Award).

Additionally, Matt Wynne of Cucumber Ltd devised Example Mapping, a lightweight workshop technique for use before translating user stories into Gherkin scenarios. Using sticky notes in four colors — story (yellow), rule (blue), example (green), and question (red) — to organize a discussion in a short time (around 25 minutes), this technique has been widely adopted as a way to converge a Three Amigos discussion onto concrete examples rather than letting it sprawl.

Ubiquitous Language, Acceptance Criteria, and the Three Amigos

Behind BDD’s growth into more than just a testing technique — into a discussion of the development process itself — lie practices such as:

  • A tie to ubiquitous language — just like DDD’s ubiquitous language, Gherkin scenarios become a shared vessel of vocabulary for business, development, and QA
  • The Three Amigos — the practice of gathering a business analyst (BA), a developer (Dev), and a tester (QA) together when firming up requirements, to reach agreement on scenarios in Given-When-Then form. This is a classic example of BDD being a technique for requirements analysis and collaboration, not merely test automation
  • Its relationship to acceptance test-driven development (ATDD) — ATDD also overlaps with BDD in deriving tests from acceptance criteria agreed with the business side, but BDD’s distinct contribution was bringing in the unified vocabulary of “behaviour” and the Gherkin notation

BDD’s Gains and Costs

BDD’s spread brought many teams the ideal of “tests that match the specification,” but its practical downsides have also been widely noted.

  • Over-Gherkinization — trying to write every test in Gherkin often meant that even trivial unit-level checks carried the overhead of natural language, actually hurting readability
  • Double maintenance cost — both the .feature file (scenario) and the step definition code need to be maintained, and they easily fall out of sync during refactoring
  • The fragility of “natural-language-like” text — subtle differences in phrasing can break step definition matching, and keeping wording consistent tends to become dependent on specific individuals
  • The business side doesn’t actually read it — the ideal has non-engineers reading and writing .feature files, but in practice, on many teams, it’s only developers and QA maintaining what amounts to a “custom DSL for tests”
  • Dan North’s own reconsideration — in later years, North has repeatedly stressed that BDD’s essence isn’t “the Given-When-Then notation” but “the idea of focusing on behaviour,” warning against mechanically applying Gherkin

Where BDD Stands Today

Today, BDD frameworks (Cucumber, SpecFlow, behave, Jest-Cucumber, and others) are mostly used at the E2E and acceptance-test layer, while at the unit-test level, only the vocabulary has loosely taken hold as “BDD-style assertions” — using describe/it syntax without a natural-language DSL, as in Jest, Mocha, and RSpec. As a movement to “write everything in Gherkin,” BDD has receded, but the underlying idea — that a test is a specification, something that describes behaviour — has left deep roots in the describe/it syntax of xUnit-family frameworks and in how contract tests and acceptance criteria get written.

The practical settlement reached in the field can be summarized roughly as follows:

  • Write only a small number of important acceptance-criteria and E2E-level scenarios in Gherkin, using them as a tool for reaching agreement with the business side
  • At the unit-test level, skip the natural-language DSL and just borrow the describe/it vocabulary to improve readability
  • Use discovery workshops like Example Mapping on their own, decoupled from Gherkin automation, purely as a conversational tool for clarifying requirements

This view — treating “the technique of collaboration” and “the technique of automation” as separate things — is itself the best explanation of where BDD stands today, circling back to North’s 2006 insight: unraveling the confusion caused by the word “test” through the vocabulary of “behaviour.”

From This Article to the Next

What BDD tried to resolve through the vocabulary of “behaviour” was, ultimately, the question of what to verify and how to describe it. But the question at the center of the classicist/mockist controversy (covered in the previous chapter) — how to treat the other objects a test’s subject depends on — still remains. The next chapter traces the taxonomy of test doubles (stubs, mocks, fakes, spies) and how the technique of mocking itself has developed over time.

← Back to The Lineage of Software Testing