To start let’s define what Test Driven Development (TDD) is. TDD is a methodology and discipline for developing code. It flips the historic development strategy on its head where instead of writing code first then writing tests, TDD is where a test is written first and then
An important point to make at this point is that with TDD it’s “Incrementally derive solutions to problems”. This means that you write one test at a time and incrementally solve the test case. For example, write a test for one case, test, develop a bit, and test again, add in another test case, test, develop a bit, and test again and keep iterating till you are confident that your as many test cases have been covered as possible.
This may seem simple enough but what are the benefits, how will this improve the quality of software developed.
- Lesser time debugging – Every developer has had to spend time debugging code, it’s just a question of how much time. So surely by incrementally writing tests and testing, we know that the last change caused the test/s to fail. It allows us to faster identify what and where the bug is.
- Documentation is written – Every software needs some form of documentation, this can include explanations but generally, there is sample code provided. The great news is that with TDD a large portion of your code snippets will have already been written.
- Ready to go production code – With TDD adding on extra code should enable you to have ready to deploy code at any moment. Considering that you will constantly be running tests you should be at most one test away from a working code base.
- Well written and testable code – Sometimes code can be written in such a way that it is very difficult to write tests for. With TDD they are already written for testing in mind.
At this point I can see only one disadvantage, you’ll have to continually build the project and run tests.
How much do you need to test? Well, there will be certain methods which will be tested via other tests such as getter and setter methods so these might not need testing depending. Testing should also be broken up to the module boundaries. For example, if you are writing an application that has to interact with another system via an API, you don’t need to test the other system, instead can “mock” the API with expected results that the API defines. The API should have its own unit tests written to ensure that the API works as expected. There are many libraries out her for mock testing such as Mockito and JMock.
There is a very good blog written by “Uncle Bob” who has come up with three rules for TDD:
- Write production code only to pass a failing unit test.
- Write no more of a unit test than sufficient to fail (compilation failures are failures).
- Write no more production code than necessary to pass the one failing
Here’s a great video to which which also includes “Uncle Bob”: