Skip to content
behaviour-driven.org

Concept

Test Driven Development: The Practice That BDD Grew Out Of

Test driven development is the practice of writing a failing test before the code that satisfies it, in cycles small enough that each one takes minutes. It was set out most influentially by Kent Beck, and it is the practice behaviour driven development grew directly out of.

The cycle is three steps. Write a test for behaviour that does not exist, and watch it fail for the right reason. Write the least code that makes it pass. Then improve the structure while the test holds you to the behaviour. Red, green, refactor.

Why the first step matters most

Writing the test first is not a scheduling detail. It forces a decision about what the code should look like from the outside before any of the inside exists, and that decision is easier to make well when no implementation is pulling at it.

It also constrains scope. A developer who writes code first tends to write the code they expect to need. A developer who writes the test first writes only what the test demands, which is a reliable way to build less.

The arc practitioners describe

People who have taught TDD report a fairly consistent sequence in how it is learned.

A developer starts writing unit tests around code they have already written, using a test framework, and gains confidence from having them. Then they try writing the test first and notice it keeps them from over-building. Then they return to code they have not seen for months and find the tests explain how it works. At some point they realise that writing the test first is how they discover the interface, which makes it a design activity.

The last step is the interesting one. Expertise in TDD arrives when a developer realises the practice was about specifying behaviour rather than about testing. Dan North’s account of inventing BDD starts precisely there: if the practice is about behaviour, the word “test” is actively getting in the way of teaching it.

Where TDD ends and BDD begins

TDD operates inside the code, in the language of the code, for an audience of developers. It answers whether the unit does what the developer intended. It cannot answer whether the developer intended the right thing.

Behaviour driven development keeps the rhythm and moves the outer loop to a level a stakeholder can read, so that the intent itself can be checked before the code exists. The comparison of the two sets out where each belongs. The short version is that they are not alternatives, and a team practising only the outer loop has a slow suite with poor diagnostics, while a team practising only the inner loop builds the wrong thing precisely.

Where TDD is genuinely difficult

Two situations, and neither is a reason to abandon it.

Code with heavy external dependencies is awkward to drive from a test, and the usual response is to introduce a seam so the dependency can be substituted. That is often an improvement to the design, which is the argument for TDD restated, but it is real work and pretending otherwise loses credibility with people doing it for the first time.

Exploratory work is the second. When the shape of a solution is genuinely unknown, writing a test first means committing to an interface before there is information to choose one. The pragmatic answer is to explore in a throwaway branch and start the cycle once the shape is clear.

What the tests are worth afterwards

A TDD suite is a by-product, but a valuable one, and its value is specific: it makes changing the code safe. That is not the same as proving the code correct, and teams that expect the second are disappointed by the first.

The related trap is treating coverage as the measure. A suite written test-first tends to have high coverage as a consequence, and chasing the number directly produces tests written after the fact that assert whatever the code already does. Those tests pass forever and catch nothing, which is worse than not having them, because they cost maintenance and buy false confidence.

REDWrite a failing testdecides the interface beforeany implementation existsGREENMake it passthe least code that satisfiesit, which is how you build lessREFACTORImprove the structurethe test holds the behaviourstill while the shape changesrepeat, in minutes rather than days
Each step answers a different question. Run only the middle one and the cycle stops being a design discipline.

Frequently asked questions

What is the red-green-refactor cycle?

Write a test that fails because the behaviour does not exist yet (red). Write the least code that makes it pass (green). Improve the structure without changing behaviour (refactor). Repeat in small steps.

Is TDD about testing?

Its output includes tests, but experienced practitioners describe it as a design discipline: writing the test first forces a decision about the interface before the implementation exists. That reframing is exactly what BDD took and made explicit.

Does TDD replace a separate test suite?

It produces a unit test suite as a by-product, which is genuinely valuable. It does not cover integration, performance or whether the behaviour was wanted, so it replaces nothing above the unit level.

Do you need TDD to practise BDD?

No, but most teams that sustain BDD also work this way, because the two operate at different levels and leave a gap otherwise. Scenarios describe behaviour a stakeholder recognises; unit tests drive the design underneath.