Test-Driven Development (TDD) is a software design method based on short development iterations requiring developers to create automated unit tests that define code requirements, before writing code itself. These unit tests contain multiple assertions (returning true or false) that could be used to rapidly verify correct behavior of the code being tested.
Once the produced code passes unit tests, it could be refactored and cleaned up. Developer will be able to ensure code staying stable in the process, by running unit tests frequently. Next iteration could be started afterwards.
Writing a test before the actual code and its refactoring helps to achieve higher quality, because:
- it forces developer to refine code contracts before working on the implementation;
- it forces developer to make and keep code easily testable. This requires loose coupling and a separation of cross-cutting concerns;
- presence of unit tests gives developers more psychological freedom to experiment with the code and refactor it; managers get lower risks related to introducing high-level changes to the project.
There are some limitations of the TDD:
- badly written or simply brittle tests can create a tremendous maintenance overhead and hinder any code evolution;
- complete code coverage by unit tests creates a false perception of security and may result in less QA than needed;
- unit tests written by the same developer tend to have similar blind spots that may actually require testing.
Unit Test Code Coverage
One of the most important metrics in the Test-Driven Development is unit test code coverage. It could be calculated automatically and indicates percentage of the code that is executed while unit tests are running.
Although code coverage does not indicate quality of the unit tests, it is still a good measure of code testability. It is a common practice to set a certain code coverage threshold (i.e.: 80%) and enforce it within the continuous integration scripts. This way, if a developer commits a significant amount of code without unit tests, this is likely to break the build, forcing him to concentrate on testing his code.
Test-Driven Development plays well along with Component-Driven Development, since both of these approaches favor doing design before the actual implementation.
- Unit Testing
- Test-Driven Development on Wikipedia
- Testing MVC Controllers with Mock Containers
- Using Lokad Rules to Simplify .NET Unit Tests
- How to Use SystemUtil to Write .NET Code With Testable Sleep and Time Calls
- Shortcuts for NUnit Exception Expectations
- How to ensure that complex methods are covered with tests
- Writing .NET code analysis rules as unit tests