TDD (Test Driven Development) refers to creating an individual test first and then creating the code for that test. This is opposite of creating code and then at some later date, creating unit tests. Proponents of TDD claim that it promotes looser coupling and better code coverage. I agree that junior level developers would benefit from this; however for senior level developers it simply creates unnecessary work. I find that it is easier to create loosely coupled methods in a domain class and then simply generate the tests for those methods using a tool such as NUnit Test Generator. After the tests are generated, single tests can be run against the corresponding method in the domain class. Without code generation for unit tests, the developer has to manually create the unit tests, since the code does not exist yet. That is just about as fun as manually creating
NHibernate mappings.
NUnit Test Generator is a great way to quickly create unit tests for NUnit, csUnit, MbUnit, or Microsoft Unit Tests. It does things like min/max/null testing too. Simple interface but powerful output.
The reason why TDD works well for junior level developers is that they tend to forget to write the unit tests at all. When you write the tests first, you can never forget to write them. However senior developers are used to checking the code coverage with tools such as
NCover and
TestMatrix. It can't be any more obvious, the untested areas of your code are highlighted in red. Another way to ensure that tests are being written is to set up a code coverage threshold on your continuous integration server.
Cruise Control .NET can be set up to automatically fail when the code coverage falls below the threshold.
TestMatrix is a great testing tool that is integrated right into Visual Studio. It has a test runner, captures performance, and performs detailed code coverage. It is like a Swiss army knife, I wouldn't be surprised if the next version tested for cancer. I like it better than what is built into Microsoft Team Suite.
Below is an example of how TestMatrix highlights code slightly different than NCover. The covered areas are in green, the uncovered areas in red. The little yellow progress bars indicate the largest performance hit for particular lines. In the example below we see that logging the error is slightly more expensive than throwing it again.
When it comes down to it, your client wants the highest quality code at the lowest price. They could really care less if you wrote the tests first or the code first. A good way to blow money and time on your project is to write your unit tests manually. If you are on a fixed bid enterprise project, this can mean the difference between success and failure. I have seen it first hand.
Having unit tests with good code coverage ensures reliability but it does not ensure maintainability. You can still have a junior developer do TDD and create crap code. The only way around this is to do paired programming or code review.
Which ever way you choose to do your tests, creating the tests first, or creating the code first; you should always write them. There is no excuse for legacy projects that do not have tests. They should be created at the first opportunity. Unit test generation solves the problem to generate tests for legacy code and speeds along the process for new projects. To all of my fans, Q'apla! Which means success in Klingon.