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