Test Driven Development (TDD)

Definition

Test-Driven Development (TDD) is a way of driving the design of code by writing a test which expresses what you intend the code to do, making that test pass, and continuously refactoring to keep the design as simple as possible. TDD can apply at multiple levels, e.g., Customer Tests, Integration Tests, Unit Tests.

Test-Driven Development/Design follows a rigorous cycle. Start by writing a failing test (Red.) Implement the simplest solution that will cause the test to pass (Green.) Search for duplication and remove it (Refactor.) "RED-GREEN-REFACTOR" has become almost a mantra for many TDD practitioners. Understanding and even internalizing this cycle is key to being able to use TDD to solve problems.

Triggers

TDD is used any time we care about the accuracy of the code in carrying out our intent.

TDD is used for any code we intend to keep.

Forces

rapid feedback decreases a debugging mindset

small, cohesive units increase comprehension of code

code debt increases the time it takes to get legacy code under test

timeboxes limit how much code can be put under test harness

expressivity of underlying code (dsl) shortens time to write tests

the big picture helps us envision what test to write next

test after instead of test first may reduce testability or increase cost of tests or decrease test coverage

failing tests may increase effort of getting the next new test to pass

examples vs behavior

outside in, inside out

automated or manual unit tests

setup/teardown provide a common context for several tests

Related Terms

Behavior-Driven Development (BDD) is a restatement of the rules of TDD that emphasizes the words we use to describe it. BDD emphasizes specification over verification. It emphasizes behavior over testing. To enable this, BDD replaces the common testing tools with new tools whose APIs reflect this different language. On one level BDD is just, as Dave Astels says, about TDD done well. However, there are some significant departures. For example, BDD incorporates story testing as an integral part whereas TDD and Acceptance Test Driven Development (ATDD) are separate practices. Also, BDD asserts that functionality should always be developed from the outside-in starting with the story test, whereas TDD remains agnostic on the issue of where to start and what direction to elaborate (top-to-bottom, bottom-to-top, starting with the domain, etc.)

Example-Driven Development (XDD) is another restatement of TDD that is very similar in language and intent to BDD. XDD talks about executable specifications that act as examples of a properly functioning system. XDD is somewhat less prescriptive than BDD in that it does not explicitly talk about story testing, outside-in, or replacing the tools.

Resources:

TDD Anti-Patterns by James Carr

Test-Driven Development By Example by Kent Beck

Working effectively with Legacy Code by Micheal Feathers

Test-Driven JavaScript Development by Christian Johansen