liveBook · Manning

Test-driven development

As explained in The Art of Unit Testing 3e

A development technique in which a failing test is written before the production code that makes it pass, followed by refactoring or another test.

Test-driven development, or test-first development, builds functionality in small cycles: write a test for missing behavior, see it fail, write the simplest production code to make it pass, then refactor or start the next test. The test is written as though the behavior already works, so an initial failure demonstrates that the new code is genuinely needed. section 1.10 section 1.10.1

TDD is not the same as merely having many tests, nor does it guarantee a successful project. It is a development technique; readable, maintainable, trustworthy tests and good system design remain separate skills. Treating test-first work as a substitute for those skills can leave fragile tests or poorly designed code. section 1.10 section 1.10.1

A practical TDD loop is:

  • Write one failing test that describes a small piece of missing behavior. section 1.10.1
  • Change only production code until the test passes; keep the implementation as simple as possible. section 1.10.1
  • Refactor production code and tests in small steps, running the full test suite after each step. section 1.10.1
  • Repeat with the next failing test, growing behavior incrementally. section 1.10

Seeing both outcomes is a central benefit. A test that fails before the behavior exists and passes after it is implemented gives evidence that it can detect a future loss of that functionality. If a supposedly missing feature starts with a passing test, the test itself may be wrong; if it still fails after the implementation, either the test has another defect or production code does. section 1.11 section 7.2.2

Learn TDD incrementally rather than trying to master everything at once. It combines three abilities: writing good tests, working test-first, and designing tests and production code well. Focusing on one ability at a time can reduce the difficulty of learning the practice. section 1.10.2

TDD is a style choice, not a requirement. It can support quality code, tests, and design, but it has a learning and implementation cost. Writing tests after code may still be an acceptable choice when that approach fits the team. section 1.10 section 11.5.9

Figure 1.9 Test-driven development—a bird’s-eye view. Notice the circular nature of the process: write the test, write the code, refactor, write the next test. It shows the incremental nature of TDD: small steps lead to a quality end result with confidence.
01-09

Use the cycle diagram to see how a failing test, production code, refactoring, and the next test form a repeating small-step process. section 1.10

How The Art of Unit Testing 3e covers it

How deep it goes
Explains the fail-pass-refactor loop and its limits, while deferring detailed refactoring practice.
Examples
Illustrates the practice with the repeating failing-test, passing-code, and refactoring cycle diagram.
What it assumes
Starts from test-first mechanics but identifies good testing and design as separate skills to develop.
What you can do after
Practice/perform it by proving missing behavior with a failing test, implementing it, and refactoring under test coverage.
How it connects
Connects unit testing, refactoring, production code, test readability, maintainability, trust, and software design.

Also explained in

Compare how 15 books explain test-driven development →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Art of Unit Testing 3e. The section links point to the parts of the book it draws on.