What is Test Driven Development?
Test driven development defines a very rigid set of rules for developing software in which tests are written before any code and the only code written will be enough to make the tests pass. Not a single line of code that's unnecessary to make that test pass should be written. The typical development cycle is as so:
- Write a test that describes some shortcoming or missing feature in the code. The scope of these tests should be quite limited, describing a very specific feature that must be implemented, or a case in which existing features fail.
- Run the tests. The test you just wrote should fail, as you haven't yet written the code to make it pass. While this might seem like a useless step, it's important to see that yes, the test you just wrote does indeed fail and that no other tests unexpectedly fail.
- Write just enough code to make this test pass. The code is often needlessly minimal, ignoring the intent of the feature and only implementing enough to make the test pass. Early in the cycle, it's not uncommon to see empty methods or methods that simply return a constant value. Future tests will be written to further define what these methods should do.
- Run the tests again. If you didn't make any mistakes, then the test you just wrote should pass. The code written to make that test pass also shouldn't cause any other tests to fail.
- Refactor. If there are any organizational changes to be made, do them. TDD encourages frequent refactoring. Not only does it represent an evolving understanding of the problem, but TDD aids refactorings greatly. When refactoring, there's always the lingering threat that something was broken or that some small bug was introduced that will never be found. Since the tests are there as a kind of safety net, this is much less of a problem.
- Write a test to define a new feature and start the process all over again.
This is contrary to the development strategies you may be used to, in which, if tests are written at all, they're written after the fact. At that stage, these tests will also be quite high level, defining only what arguments a method should take, what it should return and any side effects it should have. The amount of code covered by your tests will be quite low, compared to developing code with TDD. Using TDD, 100% of your code should be covered by tests. In fact, much of the code will be covered by multiple tests.
When using TDD, the two most important things to remember are this:
- Code doesn't exist yet until it's tested. Untested code shouldn't exist at all without a test to define what it should do.
- Run tests religiously. Tests are not housekeeping to be done in a rush at the end of the week to complete some undesirable portion of your job. Tests are an integral part of the development process. Tests should be run at every step in development, giving you constant feedback on your work.