Topic 03

Test-First: TDD & BDD

Concept

Most people assume you write code first and test it afterward. But some teams flip that around and write the test before the code. Two named practices do this: Test-Driven Development (TDD), with its tight repeating loop, and Behavior-Driven Development (BDD), which writes tests as plain-language scenarios. Both make the requirement concrete before any code exists.

It sounds backwards at first — how do you test code you haven't written? — but writing the test first forces you to decide exactly what "working" means before you start, which turns out to be a powerful discipline.

An analogy: writing the answer key before the exam. If you know exactly what a correct answer looks like up front, every question has a clear, gradeable target — and you can't fool yourself about whether you got there.

Test-driven development: red, green, refactor
Write a failing test
Make it pass
Refactor
Then loop: the next failing test starts the cycle again.

TDD: The Red-Green-Refactor Loop

Test-Driven Development follows a tight three-step loop, repeated over and over. Red: write a small test for behavior that doesn't exist yet — it fails (red). Green: write the simplest code that makes the test pass (green). Refactor: clean up that code now that it's protected by the passing test. Then repeat for the next small piece. The code grows in tiny, always-tested steps.

Why Test-First

Writing the test first has two big payoffs. It forces you to clarify the requirement before coding — you can't write the test without deciding exactly what the code should do. And it pushes you toward testable design, because code that's hard to test is usually a sign of code that's tangled. The test isn't an afterthought checking your work; it's a specification you write down first and then satisfy.

BDD: Behavior in Plain Language

Behavior-Driven Development takes the test-first idea and writes the tests in near-English scenarios that non-developers can read, usually in a "Given / When / Then" form: Given a user with a habit, When they check it off, Then the streak goes up by one. This lets product people, testers, and developers agree on behavior in the same words. BDD is as much a collaboration practice as a testing one — it gets everyone describing behavior the same way.

Not All-or-Nothing

You don't have to adopt these purely. Many teams use strict TDD for the tricky, high-risk parts and write tests after the fact for the simpler ones. Doing some test-first work where it helps most is far better than an all-or-nothing stance. The goal isn't ideological purity; it's clear requirements and well-tested code, by whatever mix gets you there.

On Cadence, the rule "a streak resets after a missed day" is fiddly and easy to get wrong, so Marcus writes the failing test first: set up a habit, skip a day, assert the streak is back to zero. Then he writes just enough code to make it pass, and cleans it up. He knows exactly when he's done — the test goes green — and that test now documents the rule forever, for whoever touches it next.

Common Confusions
  • "Writing tests first is slower, since coding comes second." It often saves time overall by preventing rework and clarifying the requirement before you build the wrong thing.
  • "BDD is just a testing tool." It's mainly a collaboration practice — getting product, testers, and developers to agree on behavior in shared, plain-language scenarios.
  • "You must do pure TDD or you've failed at it." Partial adoption is common and useful — test-first the tricky parts, test-after the simple ones. The mix that produces clear, tested code is what counts.
Why It Matters
  • Test-first is a defining practice of disciplined teams, and "red-green-refactor" is a phrase you'll hear often — this is what it means.
  • It directly connects acceptance criteria (Chapter 4) to executable checks: BDD scenarios are basically acceptance criteria turned into tests.
  • Understanding TDD and BDD as ways to clarify requirements, not just verify code, shows why teams bother writing tests before the code at all.

Knowledge Check

What is the red-green-refactor loop in TDD?

  • Write a failing test, make it pass, then clean up the code, and repeat
  • Write all of the code first, then add tests for it once it's all finished
  • Colour the user interface red, then green, then refactor the look
  • Plan the whole project in three big phases done once each

What is a key benefit of writing the test first?

  • It forces you to clarify exactly what the code should do before building it
  • It makes the finished program run very much faster for all of its end users somehow
  • It lets the team skip designing the software entirely
  • It guarantees the finished code will contain absolutely no bugs

What is BDD mainly about?

  • Writing behavior as plain-language scenarios everyone can agree on
  • A way for developers alone to write tests in a secret format
  • A technique that exists purely for making the finished program run much faster
  • A way to build the software without writing any code at all

Do teams have to adopt TDD purely, all or nothing?

  • No — many test-first the tricky parts and test-after the simpler ones
  • Yes — any single team that is not doing pure TDD has completely failed at it
  • No — because TDD is only ever allowed on very large teams
  • No — because TDD only works in certain programming languages

You got correct