Skip to content
Latchkey

What Is Test-Driven Development (TDD)?

Test-driven development is a workflow where you write a failing test for the behavior you want before you write the code that makes it pass.

Test-driven development, or TDD, flips the usual order of work. Instead of writing code and then bolting on tests, you describe the desired behavior as a test that fails, then write just enough code to make it pass, then clean up. The discipline produces a safety net of tests as a side effect of building features.

The red-green-refactor cycle

TDD runs in a tight loop. First you write a test that fails because the feature does not exist yet (red). Then you write the simplest code that makes it pass (green). Finally you refactor the code and tests to remove duplication and improve clarity, keeping the test green the whole time. Each loop is small, often only a few minutes.

Why write the test first

Writing the test first forces you to define what "done" means before you start. It nudges you toward small, testable units and clear interfaces, because code that is hard to test is usually hard to use. The failing test also proves the test can fail, so a green result later actually means something.

A worked example

Suppose you need a function that adds two numbers. You first write a test asserting that add(2, 3) returns 5. You run it and it fails because add does not exist. You write the function, run the test, and it passes. Then you add a test for negative numbers and repeat.

A first red-green step
test("adds two numbers", () => {
  expect(add(2, 3)).toBe(5);
});

function add(a, b) {
  return a + b;
}

What TDD is good and bad at

  • Strong fit: pure logic, parsers, calculations, and well-defined units.
  • Weaker fit: exploratory UI work or code whose shape is still unknown.
  • It produces fast regression coverage almost for free.
  • It is a design tool as much as a testing tool.

TDD and continuous integration

Because TDD leaves behind a fast, deterministic test suite, it pairs naturally with CI. Every push runs the same tests the developer ran locally, so the green build on the pull request reflects real, intended behavior rather than a hopeful guess.

Keeping the loop fast

TDD only works when the feedback loop stays short, both locally and in CI. When the suite grows, running it on faster runners and in parallel keeps each push under a minute or two. Latchkey runs that suite on quick managed runners and splits it across them so the green check arrives before the developer loses context.

Key takeaways

  • TDD means writing a failing test before the code that satisfies it.
  • The red-green-refactor loop builds regression coverage as you go.
  • It doubles as a design tool that favors small, testable units.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →