Test-driven development (TDD) is a software development technique that is based on the repetition of a short development cycle. The developer writes an automated test that is designed to fail at first, but will pass once that designed improvement or enhancement is complete. The developer then first writes code to pass the test, and then improves the code to continue to pass the test, but in the most logical and best written way. TDD can be used with writing new projects, or even to improve existing legacy code. One fundamental philosophy of TDD is that instead of coding for today and designing for tomorrow, one codes for tomorrow and designs for today.
(from Test-Driven Development by Example)
This cycle is repeated with each desired piece of functionality. If at any point other tests besides the newly introduced test fail, the developer should revert instead of undergoing extensive debugging. The goal is small runs repeated often, giving easily revertible checkpoints.
Studies have found that TDD improves developer productivity. By testing every piece of code, developers can gain a greater level of trust of their code. TDD also helps developers tackle small pieces of a project when necessary. Despite the additional amount of test code, total code implementation time is usually shorter, and large endemic problems are discovered before they are given the chance to grow. It also leads to more modular and flexible code, as small projects are undertaken often, forcing the developer to code in such manageable segments.
Some products are hard to test, such as user interfaces or those that need a specific network configuration. Management must support TDD, as otherwise the time spent writing tests can easily be attributed as wasted time. Tests must be written properly, as badly written tests can require significant effort to maintain or even lead to false positives leading to the ignoring of tests. Tests must be all run throughout the process, if a large number of tests fail late in the development cycle they must be individually fixed instead of rashly adjusted. If a developer fails to have an accurate understanding of the requirements for a module, their test will be incorrect, as will the code written for that test. Finally, TDD might lure developers into a false sense of security, leading them to skip testing such as integration testing or compliance testing.