TDD: It's not just about the Tests
I work as a freelancer and so get to see lots of different setups within development companies. In my experience to date one thing that varies widely from company to company is the use of unit tests and in particular the opinions concerning the use of tests.
The common theme I hear against the use of TDD is:
That will just leave us with more code to maintain, which we will have to change when we make changes and so on…
There is some truth to this as all the code in a project is subject to maintenance. A good suite of unit tests can dramatically increase the stability of the system, if done right, which is a huge caveat.
TDD: The Bad Parts
Extra Development Required
I've seen bad tests which were indeed a maintenance headache, didn't serve a great deal of purpose and led to developers writing poorly constructed unit tests AFTER they had completed their development as some kind of post development administration. In this case, it was a waste of time adding the tests and they were eventually removed from the project.
Misuse of Mock Objects
This is a very specific point about TDD which would only be understood by a developer who has had exposure to TDD. Mocking objects can be difficult and is a common cause of confusion amongst developers and potentially the greatest threat against the maintainability of TDD code. This is not the fault of Mock objects, rather the way this code can creep in as classes within an application begin to grow.
TDD: The Good Parts
Stop Bugs getting into Production
I've worked on projects where the tests have been great and really conveyed the power of TDD drawing a line of stability under the code base and catching bugs before they hit the development environment, let alone production.
Catching bugs as part of the build process is the headline selling point of TDD.
TDD: The Awesome Parts
Once a developer gets up and running with TDD their productivity can be increased dramatically. There have been occasions where I have written code with unit tests even when the tests were not used as part of the build process for the project. I wrote the tests because I could get my stuff done quicker - even if the tests were to be binned at the end of my development task.
The Feedback Loop
A point I often see overlooked when writing tests is the feedback loop. If I had to pick the most important benefit of writing tests this would be it. The feedback loop adds a huge productivity boost when I'm writing code in the style of Red, Green, Refactor. The feedback loop is the process of writing a small snippet of code and getting a rapid answer (feedback) confirming its correctness. This process is repeated in a loop as the functionality is built up hence the name feedback loop.
Encourages SOLID Design
If used correctly, TDD will force some SOLID design principles by default. In particular the Single Responsibility, the Inversion of control and Dependency Injection principles. That's three out of the five points crossed off!
Great API Design
When using TDD correctly I find that a clean API falls out of the process. This is in part due to the Single Responsibility from the SOLID design principles as the end result is lots of methods that perform one particular task. It will also help us to become aware of increasing dependencies for a given class - as constructor bloat will be spotted sooner when writing mocks for our tests.
High Speed Debugging
With good tests in place the time spent debugging can be dramatically reduced. I work a lot with ASP.Net applications and so spend a lot of time in the browser. I'm sure any web developer would have written some code, fired up the browser, spotted a bug, tweaked the code, re-opened the browser to re-test and so on. I would be too afraid to put a number on how many times I have performed this action - it would probably be a googol. This process is a (long winded) feedback loop.
When partnered with a design pattern like MVC or MVP, a large majority of the application can be developed without touching the browser. A couple of projects ago I was working with the MVP pattern and TDD. I only had to open the browser at the end of the development process just to plug in the necessary web controls and check over the layout and I was done. My productivity was high and by the time I got to using the browser all my code worked first time.
TDD is not for Everyone
I'm a fan of TDD, but only TDD done right. This blog post lists a lot of benefits in using TDD, but that doesn't mean everybody should dive in and start creating unit tests for everything. TDD is not easy, it takes time to learn and get right and there is a risk that it could be a time sink for a project if the entire development team does not buy into its usage.
Where to Start with TDD
If you have yet to dive into TDD I recommend the following resources to get started:
Also consider reviewing BDD. Many of the "awesome" points listed in the blog post are possible with BDD.