What Is BDD and How It Differs from TDD

8 min read

Before you write a single .feature file, it's worth understanding why BDD exists and what problem it solves. The short answer: requirements misunderstanding. Developers build the wrong thing, testers discover it late, and the blame game begins. BDD is a practice designed to prevent that specific failure mode.

The problem BDD solves

Picture a user story: "As a user, I want to reset my password." A developer reads it and builds a reset flow that sends a link to the registered email. A tester reads it and expects a security question. A product owner imagined a phone-based OTP. Three people, three interpretations, zero conversations. The feature ships, the wrong thing ships.

BDD forces the conversation early. Before any code is written, the team sits down and writes concrete examples — in plain English — of exactly what the system should do. Those examples become Gherkin scenarios. Those scenarios become executable tests. The ambiguity never gets the chance to cause a production incident.

TDD: the developer's practice

Test-Driven Development is about implementation quality. The cycle is:

  1. Write a failing unit test for a small piece of code
  2. Write just enough code to make the test pass
  3. Refactor the code, keeping the test green

TDD tests are code. They reference classes, methods, and private behaviour. A product owner looking at a TDD test sees assertEquals(3, cart.getItemCount()) and may or may not understand it. That's fine — TDD tests are a developer tool for driving design.

BDD: the whole-team practice

BDD starts in the same place as TDD — before the code — but at a higher level of abstraction. Instead of a failing unit test, you write a Gherkin scenario:

Feature: Password Reset
 
  Scenario: User resets password via email link
    Given the user has an account with email "alice@test.com"
    When the user requests a password reset
    Then a reset link is sent to "alice@test.com"
    And the link expires after 24 hours

This is not test code. Anyone on the team — developer, tester, product owner, business analyst — can read it and verify that it matches their understanding. The scenario is a specification written in natural language. Cucumber's job is to turn it into an executable test by mapping each step to a Java method.

The Given/When/Then structure is deliberate:

  • Given — the state the system is in before the action (preconditions)
  • When — the action a user or system takes
  • Then — the observable outcome that confirms the behaviour is correct

This three-part structure forces the scenario writer to separate context, action, and outcome — the exact pieces needed to verify a feature without ambiguity.

BDD is not just testing

This is the most misunderstood aspect: BDD is a collaboration practice, not a testing tool. Cucumber is just the tool that turns the collaboration output (feature files) into runnable tests.

The value is in the conversation that happens before the scenarios are written. When a developer, a tester, and a product owner sit down together to write examples — a practice sometimes called the Three Amigos session or Example Mapping — they surface edge cases nobody had thought of. "What if the email doesn't exist?" "What if the user tries to reset twice in an hour?" These questions, answered upfront, prevent bugs before a single line of code is committed.

The Three Amigos practice is covered in depth in Chapter 5. For now, the key insight is: Cucumber is only as good as the quality of the collaboration that produces its feature files.

What Cucumber actually does

Cucumber reads .feature files written in Gherkin and matches each step to a step definition — a Java method annotated with @Given, @When, or @Then. When you run the tests, Cucumber:

  1. Finds .feature files in your configured location
  2. Parses each scenario into individual steps
  3. Looks for a step definition method whose annotation text matches each step
  4. Executes the matched method
  5. Reports pass, fail, or undefined (no matching step definition found)

The feature file stays readable plain English. All the Selenium, Rest Assured, or database logic lives in the Java step definitions. Business people can read the feature; developers can read both.

Where Cucumber fits alongside TDD

BDD and TDD are complementary, not competing. A healthy project uses both:

  • Unit tests (TDD) — fast, developer-facing, testing individual classes and methods
  • BDD scenarios (Cucumber) — slower, team-facing, testing observable business behaviour

Cucumber scenarios typically run at the integration or end-to-end level — they drive Selenium for UI behaviour or Rest Assured for API behaviour. Unit tests protect implementation details; BDD scenarios protect business requirements.

Where this course is going

You'll spend Chapters 1 and 2 learning Gherkin — how to write scenarios that are clear, concise, and actually useful. Chapters 3 and 4 go deep on step definitions: parameters, hooks, sharing state across steps, and integrating with Selenium and Rest Assured. Chapter 5 is about putting BDD into practice with stakeholders. Chapter 6 is a capstone: a full BDD test suite for an online banking application.

By the end you'll have the technical skills to build a Cucumber framework and the collaborative understanding to use it in a way that actually reduces bugs.

TDD vs BDD — side by side

TDD

  • Write a failing unit test

  • Write code to pass the test

  • Refactor

  • Developer-focused

  • Tests written in Java

  • Tests reference classes and methods

  • Fast — milliseconds per test

  • Tool: JUnit 5 / TestNG

BDD

  • Write Gherkin scenarios (team activity)

  • Implement step definitions

  • Run feature files as tests

  • Whole-team practice

  • Scenarios written in plain English

  • Tests describe observable behaviour

  • Slower — seconds to minutes per scenario

  • Tool: Cucumber

⚠️ Common mistakes

  • Thinking BDD is just Cucumber. Teams adopt Cucumber without the collaboration practice and end up with Gherkin-wrapped Selenium tests nobody reads. The scenarios exist but no business stakeholder ever reviewed them. You get all the complexity with none of the benefit.
  • Writing TDD-style assertions in Gherkin. Steps like Then the variable cartCount equals 3 are implementation leaking into the specification layer. Keep Gherkin at the business level: Then the cart shows 3 items.
  • Skipping the Three Amigos. Writing scenarios alone (as a QA engineer) and throwing them over the wall to developers breaks the shared-understanding model. BDD only works when the conversation happens first.

🎯 Practice task

No code this lesson — the goal is to build the mental model. 20 minutes.

  1. Pick any feature from an app you use regularly (e.g., Google Search, a banking app, a shopping site). Write 3 Gherkin scenarios for it by hand — no tools needed, just a text editor. Focus on the Given/When/Then structure. Ask yourself: could a non-technical colleague read this and confirm it matches their understanding?
  2. Now look at your scenarios and ask: are any steps describing implementation details (button IDs, URL paths, API endpoints)? Rewrite those steps in business language.
  3. Stretch: write one scenario where the Given describes a state that requires some setup — a logged-in user, an existing order, a populated database. Think about how step definitions would need to create that state programmatically.

Next lesson: the Maven dependencies and project structure that turn these plain-text scenarios into runnable Java tests.

// tip to track lessons you complete and pick up where you left off across devices.