Testingintermediate
Test-Driven Development (TDD)
A development workflow where a failing test is written before the implementation code, following a strict red-green-refactor cycle.
Write a failing test, make it pass, then improve the code.
TDD is like a sculptor who first describes precisely, in words, exactly what the finished statue's specific pose and expression should look like (the failing test) before touching the marble, then carves only enough to match that exact description (minimal implementation), and only afterward smooths and polishes the surface (refactor) — confident that the carved shape's core measurements already match the original written description, checked and rechecked, throughout the smoothing process.
Key Concepts
1
red write a test for behaviour that does not exist -- it fails
green write the simplest code that passes it
refactor improve the design, with the test protecting you2
The order is the point. Writing the test first forces you to decide what the code should do before
deciding how — which usually produces a simpler interface, because you are the first caller.
3
A worked cycle.
// red
it('returns 0 for an empty cart', () => {
expect(total([])).toBe(0);
});4
// green -- deliberately minimal
const total = () => 0;5
// red again
it('sums the item prices', () => {
expect(total([{ price: 10 }, { price: 5 }])).toBe(15);
});6
// green
const total = (items) => items.reduce((s, i) => s + i.price, 0);7
Writing return 0 looks absurd and is the discipline: it proves the test fails for the right reason, and
each test drives one more piece of behaviour.
return 0
8
What it actually buys, beyond the tests themselves.
9
A test suite that is complete by construction. Every line exists because a test demanded it.
10
Refactoring with confidence. The tests were written against the behaviour, so they still pass after the
implementation changes.
11
Better interfaces. Code that is awkward to test is usually awkward to use, and you find that out
immediately rather than at the third call site.
12
Where it does not fit. Exploratory work where you do not yet know what you are building. UI layout.
Code whose correctness is visual. And anything where the test would be a restatement of the implementation.
13
The honest position. Strict TDD on everything is rare in practice. Writing the test first for logic with
clear inputs and outputs — pricing, validation, parsing, state transitions — is where it pays, and that is
a large share of the code that matters.
14
And the failure mode. Tests written after the fact tend to assert what the code does, including its
bugs. Writing the test first is what stops that, which is the argument even for people who do not follow the
cycle rigidly.
15
What the interviewer is probing.1. "Describe the cycle." Probing: the process. Stalls: "Write tests first." Moves up: red,
green, refactor — a failing test, the simplest code to pass it, then improve the design with the
test as a safety net.
16
2. "What does TDD give you beyond coverage?" Probing: the real benefit. Stalls:
"Confidence." Moves up: design pressure — code that is hard to test is usually badly coupled, so
the difficulty is feedback.
17
3. "When would you not use it?" Probing: honesty. Stalls: "Always use it." Moves up:
exploratory work where the design is unknown, or UI layout where the assertion is visual.
18
4. "Why write the failing test first?" Probing: the point. Stalls: "Convention." Moves up:
a test that has never failed proves nothing — you have not seen it detect the absence of the
behaviour.