Test-driven development turns the usual coding routine on its head: you write a failing test first, then write just enough code to make it pass, and finally tidy the code without breaking the test. This red–green–refactor loop is one of the most disciplined approaches to software engineering.
What is test-driven development?
Test-driven development (TDD) is a software development practice in which tests are written before the production code they will verify. The developer thinks through what the code should do — what inputs it accepts and what outputs it produces — and expresses those expectations as automated tests. Only then does the developer write the code that satisfies them.
This inverts the more intuitive "write code, then test it" approach. The discipline forces clarity about requirements: you cannot write a test without first knowing precisely what the function is supposed to do.
What is the red–green–refactor cycle?
TDD follows a strict three-phase loop, named after traffic lights:
| Phase | Colour | Action |
|---|---|---|
| Red | 🔴 Failing | Write a test for a small piece of new functionality. Run it. It must fail — if it passes, the test is wrong or the feature already exists. |
| Green | 🟢 Passing | Write the minimum code necessary to make the test pass. Do not worry about elegance yet. |
| Refactor | ⬜ Clean | Improve the code's structure, remove duplication, and clarify naming — all while keeping every test green. |
After refactoring, the cycle repeats with the next piece of functionality.
How does TDD work? A worked example
Task: Write a function is_even(n) that returns True if n is even and False if n is odd.
Step 1 — Red: write a failing test
# test_is_even.py
def test_even_number():
assert is_even(4) == True
def test_odd_number():
assert is_even(7) == False
def test_zero():
assert is_even(0) == True
Running these tests now fails with a NameError — is_even does not exist yet. ✓ (Red)
Step 2 — Green: write the minimum code
# is_even.py
def is_even(n):
return n % 2 == 0
Run the tests. All three pass. ✓ (Green)
Step 3 — Refactor
The function is already clean and simple — no refactoring needed this cycle. If the function were more complex (with repeated logic or poorly named variables), this is where those issues would be fixed.
Next cycle: write a new failing test for a new requirement (e.g. negative numbers) and repeat.
What types of test are used in TDD?
| Test type | What it tests | Typical scope |
|---|---|---|
| Unit test | A single function or method in isolation | One function, independent |
| Integration test | Multiple components working together | Two or more modules |
| System test | The entire system against its requirements | End-to-end |
| Acceptance test | Whether the system meets the user's needs | Business-level requirement |
TDD primarily uses unit tests — small, fast, focused tests of individual functions. Unit tests run in milliseconds, so developers can run the full test suite after every change.
How does TDD connect to the software development life cycle?
The SDLC (software development life cycle) describes how software is built from requirements through to deployment. TDD fits within the implementation and testing phases, replacing the traditional "code first, test later" approach with an interleaved loop.
In agile methodologies — where development happens in short sprints — TDD is a natural companion: each sprint adds new features, and the growing test suite (called a regression suite) automatically verifies that new code has not broken existing functionality. Running the suite after every change catches regressions immediately, when the cause is fresh in the developer's mind.
Traditional approaches often discover bugs late, when the code is complete and the developer has forgotten the detailed reasoning behind each decision. TDD catches them within minutes.
What are the advantages and disadvantages of TDD?
| Aspect | Advantage | Disadvantage |
|---|---|---|
| Code quality | Forces modular, testable design | Extra time writing tests upfront |
| Bug detection | Catches regressions immediately | Tests must themselves be correct |
| Documentation | Tests serve as living examples of correct behaviour | Test suite maintenance adds overhead |
| Confidence | Refactoring is safe (tests confirm nothing broke) | Difficult to apply to GUIs or hardware |
| Requirements clarity | Cannot write a test without understanding the requirement | Requires discipline to maintain the cycle |
Frequently asked questions
Is TDD the same as just testing your code?
No — the key distinction is timing. Testing after writing code (sometimes called "test-last development") is common but less rigorous: there is no guarantee every line is covered, and it is tempting to write tests that confirm what the code already does rather than what it should do. TDD insists the test is written first, when the developer is still thinking about the requirement rather than the implementation. This makes the tests genuinely independent checks on the code's behaviour.
Does TDD guarantee bug-free code?
No. TDD reduces bugs significantly by catching regressions immediately and forcing clear specification of expected behaviour. However, tests can only verify the cases you thought to test. A function might be correct for every tested input and still fail on an untested edge case. TDD is one layer of quality assurance, best combined with code review, integration testing, and user acceptance testing.
Do I need to know TDD for the GCSE exam?
GCSE specifications cover testing strategies including unit testing, integration testing, and acceptance testing. TDD is often mentioned as a software development methodology. For the exam, you should understand what TDD is, describe the red–green–refactor cycle, and explain its advantages (catching bugs early, clear requirements) and disadvantages (time overhead, not suitable for all types of code). Writing test code is not usually assessed in written papers.
What is the difference between TDD and BDD?
Behaviour-Driven Development (BDD) extends TDD by writing tests in near-natural language that describes the expected behaviour from the user's perspective, often using a structured format like: Given [context], When [action], Then [outcome]. BDD makes tests more readable to non-technical stakeholders. TDD focuses on the technical correctness of functions; BDD focuses on user-visible behaviour. BDD is beyond GCSE scope but is worth knowing as context for future study.
Practise building quality software from first principles — Professor Turing at aitutors.me will guide your understanding of testing, the SDLC, and everything the specification requires.