What is test-driven development (TDD)?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
TDD is writing the test before the code, in a short loop usually described as red, green, refactor:
- Red — write a test for behaviour that does not exist yet. Run it and watch it fail. A test that passes immediately is testing nothing.
- Green — write the least code that makes it pass. Ugly is fine at this stage.
- Refactor — clean up now that the test protects you, then run it again.
// red
test("applies a 10% member discount", () => {
expect(priceFor(100, { member: true })).toBe(90);
});
// green
function priceFor(price, user) {
return user.member ? price * 0.9 : price;
}
// refactor — extract the rate, add the next failing test
What it actually buys you
The benefit people notice first is coverage, but that is a side effect. The real gains are design pressure and fast feedback: writing the call before the implementation forces you to think about the interface from the caller's side, and code that is awkward to test is usually code with too many dependencies. Because each loop is a minute or two, defects surface while the change is still small.
Where it fits badly
TDD works best where behaviour is expressible as input and output — business rules, parsers, calculations, reducers. It fits poorly when you are exploring an unfamiliar API, prototyping something you may throw away, or working on visual layout, where a snapshot or a human eye tells you more than an assertion.
Common misreadings
TDD does not mean 100% coverage, and it does not replace integration or end-to-end tests — unit tests alone will not catch two correct components wired together wrongly. It also is not all-or-nothing: applying it to the tricky core of a feature and writing the rest normally is a perfectly reasonable middle ground.
