I am convinced that Test-Driven Development is the single greatest hope that our industry has, as a whole, for improving the development and design of useful, practical, low-defect applications, and I find it frustrating that, in some places, it has taken off, while in other places, it remains a ‘nice idea.’
I saw a post on the newsgroups recently offering some ‘good tips’ for developers. These tips, largely a nice collection of tried-and-true practices, seemed like “yet another attempt” to fix the problem of bad code by making developers more aware of what to do well. Problem is that most developers don’t intentionally develop bad code. They develop good code, and then, in support, that code is expected to flex in ways that the original designer did not intend.
Over time, the code is modified through Quick-Fix efforts that may, or may not, recognize the original design. Opportunities for refactoring are not recognized because support teams are not paid to notice the original design intent… they are paid to fix the code. In doing so, they make mistakes that build up over time.
I think that test first development, as a SUPPORT discipline, would be the best way to highlight the need for refactoring code when it needs it, and not later, after it has becomed a tangled mess.
So, if you are in an organization that has not yet taken up Test-Driven Development, consider convincing your Support team to place these two rules into effect:
1) No code from development will be accepted into support without at least 80% code coverage in unit tests, and
2) No fix may be checked in for production deployment without all unit tests also working, and all new code getting unit tests.
Nothing will drive unit tests faster than making it a requirement of the support team, and nothing will lower the cost of ownership faster than recognizing the correct time for refactoring. I’m convinced that this small change can make a huge impact.
So if the support team adopts #1, what do I tell the development team that has no tests for 500,000 lines of code. We can’t seem to convince management that it is worth the time to stop new development for two months while we write some automated tests that the client will never know are running.
1) How do you *convince* management that we should be required to do this?
2) How do you *convince* developers that think it is a "nice idea" but they code "well enough without it"?
3) If you get past number 2 how does a team get started when the code base is already in place and it would take a fair amount of time to learn effective testing and then to build tests around the code and business logic?
How do you eat a whale… one bite at a time.
When support opens up a project with 100,000 lines of code, and wants to add 50 lines, they should add 10 test cases to cover the base conditions and the new conditions for the modified modules. (Base conditions first, compile, run test harness, add new test cases to cover new functionality, compile, run (watch new ones fail), code new functionality, compile, watch new ones succeed and existing ones succeed… now check it in.
This pays for itself in support without a single line of code delivered from dev.
That said, management is the easy part. You run a pilot to prove out the idea. You send the developers for a single project to training on TDD. You then require the developers to follow TDD methods when writing the code. Observe the length of the Integration Test phase. Observe the number of recorded defects. (Shorter, Fewer). Now, go back to management and show them that you can save 15% of the cost of rolling out an app by spending 10% more up front. Then show them that you can save 25% of the cost of quick-fix engineering by having the unit tests in place at time of change… managers like saving money.
As for convincing developers, that’s not that hard. Pilot with a dev team composed of five early adopters and one luddite. Now, have them share their training with their coworkers in informal brown bags. Have them show off things like automated build verification tests.
Developers respond to show-offs.
As for existing code base, see above recommendation for support: for every few lines of new or changed code, there should be another test case added to the list. Therefore, changes to 200 lines would mean creating at least 50 test cases.
crawl, walk, run
To date, my problem has been that I write the code with tests and the support engineers ignore it. I come back in a few months and the tests are broken.