Steve McConnell's Code Complete points to an interesting study where the defect detection rates of many common-defect detection techniques used individually have a modal rate of about 30-50%. Unit testing under that study had a lowest defect detection rate of 15%, a modal rate of 30% and highest rate of 50%. Given the focus that different methodologies such as XP have had on unit testing that is quite low and a little disappointing. However the study noted;
When used individually, no method had a statistically significant advantage over any of the others. The variety of errors people found was so great, however, that any combination of two methods - including independent groups using the same method - increased the total number of defects found by a factor of almost two.So unit testing used in conjunction with regression testing (for instance in continuous integration) improves the value of unit testing. From the list in that book of the value of the different removal methods, we have decided to use unit testing in conjunction with formal code reviews and formal design inspections. However, our design inspection are based on the stories (use cases) and are a couple of pages to make sure the starting point for coding is ok and agreed on. Unit Testing has value beyond defect removal rates. It is amazing how developer confidence improves with unit testing. Kent Beck writes:
While there are many rational explanations for why programmers should automate tests, for me the compelling argument is emotional. When I write automated tests I feel more confident in my work than when I don't write automated tests.Which I agree with. The unit testing adds a sense of completeness to code as well. With all unit testing libraries and the integration of unit testing into IDEs it has become very simple to do so as part of a project. But the study that McConnell points to suggests that used in combination with another defect removal methodology they are even more effective.
Unit testing has become nearly universal in penetration amongst engineering shops. The hump to implement it can be high but the value in terms of quality is so instantaneous a trade off that it is invaluable. Michael Pederson writes:
I first learned about automated unit testing about four years ago, and decided to experiment with it. I quickly found out that code I thought I had thoroughly debugged had errors in it.My experience is the same. It used to be that when you went back to code you wrote a year ago you would wonder what the hell the developer (ie you) was thinking. Now that little feedback loop is within fifteen minutes. The current project we are doing makes the Oracle Service Bus [OSB] the central brain between all the different systems. We are architecting it as it should be, but there is no real mechanism to place unit tests on the workflow within the OSB. It is also the most fragile part of the system. Namespaces are particularly susceptible to breakage in that environment.
Interesting comparison of test driven development and writing unit tests after the problem has been solved in an article from Peer Siebel;
Then bloggers were arguing back and forth about what this means. I don't think it means much of anything--I think test-driven design is great. I do that a lot more than I used to do. But you can test all you want and if you don't know how to approach the problem, you're not going to get a solution.Lately we have been pair programming over the problem and solving it in java code, webservices and the OSB. Afterwards we have been running off and putting unit tests over it. To be truthful I have been really enjoying this pattern of work. It helps that Patrick is an entertaining fellow to work with, but we have had two eyes on the problem and have talked out design decisions and choices while we are working. Additionally for me there is a large element of training as well as I come up to speed on a new and complicated system. The added bonus is we are getting a lot of work done by working in this manner.
There is a posting on the perl journal about test driven development and how being dogmatic about a quality approach is never fully fruitful. One of the problems in software is feature volatility and while functional testing offers a mechanism to test features it is also plagued with the same problem.
It has been my experience that unit testing does produce higher quality and more robust code during development. It is more laborious and does take up more time, but the number of times untested code has sucked up two developers for two days each in tracing down difficult and obscure behaviour it is worth it. More so, those that don't cover their code fully with unit tests do have the buggiest code.
There was a time when the bare minimum of quality in a software project was continuous integration and a central source repository. Now, it is unit testing as well. But again, it doesn't require 100% unit testing coverage, or test driven development. One of the things that makes code so durable is that if you get it right once, it tends to work the same forever. So code that has passed QA is normally good for production in most cases, short of gnarly edge cases.
There is also the issue that working code in a crunch environment is valuable, so working code will get pumped out and unit tests skipped. Features are often deemed more important during the development phase and quality only becomes important after feature complete. There is also the issue that quality can be difficult to determine until feature complete anyway as features can be negatively impacted by the different delivery mechanism for data in complex projects when they are incomplete leading to confusing bugs or quality issue reports.
Ultimately however, unit testing has raised the bar on what is the standard for quality in a software project. Codebases without test harnesses of some kind are remiss.








