Test Driven Development or Test-First Design is one of the core programming practices of XP. Many of us have learned over the years the value of writing automated tests for our code. Many of us have also learned the difficulty of writing tests after code is already in place. Test-first design takes a different, extreme approach to ensure that we test all code, all the time.
The practice of test-first design begets a changed mindset: we write tests not as an afterthought to ensure our code works, but instead as just part of the everyday, every-minute way of building software. Instead of writing our detailed design specifications on paper, we write them in code. Instead of first striving to perfectly design a system on paper, we use tests to guide our design. Instead of coding for hours at a stretch, only to find our planning went awry, we use test-first design to pace ourselves, always assuring that we are moving forward correctly with each passing minute.
Write a test that specifies a tiny bit of functionality
Ensure the test fails (you haven't built the functionality yet!)
Write only the code necessary to make the test pass
Refactor the code, ensuring that it has the simplest design possible for the functionality built to date
Test everything that can possibly break
Tests come first
All tests run at 100% all the time
Code is written so that modules are testable in isolation. Code written without tests in mind is often highly coupled, a big hint that you have a poor object-oriented design. If you have to write tests first, you'll devise ways of minimizing dependencies in your system in order to write your tests.
The tests act as system-level documentation. They are the first client of your classes; they show how the developer intended for the class to be used.
The system has automated tests by definition. As your system grows, running full regression tests manually will ultimately take outrageous amounts of time.
Development is paced. We specify tiny bits of functionality in our tests, then write a small amount of code to fulfill that specification. Rinse, repeat. Tiny means seconds to a few minutes. The code base progresses forward at a relatively constant rate in terms of the functionality supported.
Test-first design is infectious! Developers swear by it. We have yet to meet a developer who abandons test-first design after giving it an honest trial.