Skip to content

TDD / BDD

TDD / BDD

Test-Driven Development & Behavior-Driven Development

1. Overview of TDD/BDD, Development Methodologies That Drive Design by Writing Tests First and Build In Quality

    flowchart LR
    A["Tests added after code<br/>is written<br/>(quality trails, fragile to regression)"] --"Test-first<br/>design-driven approach"--> B["Red-Green-Refactor<br/>repeated in short cycles"] --"Behavior specification<br/>(Given-When-Then)"--> C["Early defect detection,<br/>improved design quality"]

    style A fill:#FFEBEE,stroke:#D32F2F,color:#000
    style B fill:#E3F2FD,stroke:#1976D2,color:#000
    style C fill:#E8F5E9,stroke:#388E3C,color:#000
  

Definition:

  • TDD (Test-Driven Development): A development methodology in which a failing unit test is written first, before the implementation code, followed by writing the minimal code to pass the test, and then refactoring — repeating this Red-Green-Refactor cycle.
  • BDD (Behavior-Driven Development): An extension of TDD that specifies a system’s behavior from a business perspective, using the Given-When-Then scenario language to build shared understanding among developers, QA, and the business.

Characteristics: (Design specification role) Tests double as design specifications, ensuring alignment between requirements and implementation. (Early defect detection) A short feedback loop (within minutes) enables early detection and correction of defects, curbing technical debt. (Refactoring safety net) Test code acts as a safety net for refactoring — guaranteeing existing behavior when improving structure.


2. Core Structure of TDD/BDD

A. The Red-Green-Refactor Cycle

    flowchart TD
    RED["RED<br/>Write a failing test<br/>no implementation yet<br/>confirm the test fails"]
    GREEN["GREEN<br/>Write the minimal code<br/>needed to pass the test<br/>pass quickly"]
    REF["REFACTOR<br/>Improve code quality<br/>remove duplication, clean up structure<br/>tests still pass"]

    RED -->|"Write implementation code"| GREEN
    GREEN -->|"Improve code"| REF
    REF -->|"Write the next test"| RED

    style RED   fill:#dc3545,stroke:#c82333,color:#fff
    style GREEN fill:#28a745,stroke:#218838,color:#fff
    style REF   fill:#E3F2FD,stroke:#1976D2,color:#000
  
PhasePurposeCore Principle
RED (Fail)Specify requirements as a test before implementationNew feature work must start with a failing test
GREEN (Pass)Implement the minimum needed to pass the testThe goal is simply to pass, even if not perfect
REFACTOR (Improve)Remove duplication, improve naming, clean up structureImprove code quality while keeping tests passing

The Three Rules of TDD (Uncle Bob)

RuleContent
Rule 1You are not allowed to write production code until you have written a failing unit test
Rule 2You are not allowed to write more of a unit test than is sufficient to fail — and not compiling counts as failing
Rule 3You are not allowed to write more production code than is sufficient to pass the currently failing test

B. Given-When-Then Scenarios (Linked to BDD)

    flowchart LR
    subgraph GWT["Given-When-Then Structure"]
        direction TB
        GIV["Given (Precondition)<br/>defines the system's initial state<br/>sets up the environment before the test runs"]
        WEN["When (Action)<br/>a specific action by the user or system<br/>executes the behavior under test"]
        THN["Then (Outcome)<br/>verifies the expected result/state<br/>confirms the system's response"]
        GIV --> WEN --> THN
    end

    subgraph TOOLS["BDD Tools"]
        direction TB
        T1["Cucumber<br/>(Gherkin language)"]
        T2["JBehave<br/>(Java BDD)"]
        T3["Behave<br/>(Python BDD)"]
        T4["Jest + Describe<br/>(JS/TS BDD)"]
    end

    GWT --> TOOLS

    style GIV  fill:#E3F2FD,stroke:#1976D2,color:#000
    style WEN  fill:#FFF3E0,stroke:#F57C00,color:#000
    style THN  fill:#E8F5E9,stroke:#388E3C,color:#000
    style TOOLS fill:#F3E5F5,stroke:#7B1FA2,color:#4A148C
  

Given-When-Then Scenario Example

Feature: Online shopping cart

  Scenario: Add a product to the cart
    Given the customer is logged in
    And   the product "Laptop" has 5 units in stock
    When  the customer adds 1 unit of "Laptop" to the cart
    Then  the cart should contain 1 unit of "Laptop"
    And   the stock should be 4 units
ComponentRoleCorresponding TDD Element
GivenSets up test preconditions and initial state@Before / setUp()
WhenExecutes the action under testInvoking the method under test
ThenVerifies the expected outcome (assert)assertEquals() / assertThat()
And / ButAdds additional conditions or outcomesChaining multiple Given/When/Then steps

TDD vs. BDD Comparison

Comparison ItemTDDBDD
PerspectiveDeveloper-centric (unit-level functionality)Business-behavior-centric (scenarios)
Writing languageProgramming language (Java, Python)Near-natural-language Gherkin
Collaboration audienceAmong developersDevelopers, QA, and the business together
Test unitMethod/class levelUser scenario (Feature) level
Representative toolsJUnit, pytest, JestCucumber, JBehave, Behave

3. Expected Benefits and Application of TDD/BDD

CategoryKey Expected BenefitsApplication and Practical Approach
Built-in qualityEarly defect detection minimizes correction cost (the 1:10:100 rule)Set up a CI pipeline gate that automatically runs TDD tests
Improved designTestable code naturally leads to single responsibility and low couplingBuild a TDD-based safety net before restructuring legacy code
Stronger collaborationBDD scenarios build shared understanding across business, development, and QADefine acceptance criteria with Given-When-Then during sprint planning
Regression preventionAutomated test code continuously guards against regressionAutomatically run the full test suite in the CD pipeline