In a recent discussion on the altdotnet mailing list, a question was raised: How to you start introducing TDD into an existing team? Bill Barry had some good thoughts on how the process might work, I suggest you check out his post.
It got me thinking about things and three questions came to mind:
- If the team is functioning and delivering software, why introduce anything at all — especially such a radical change as TDD?
- When implementing TDD, what’s the best way to get it going (i.e. mandatory/imposed, weaving in little by little, separate project, etc)?
- Won’t this just add a bunch of time to my process?
First Question: Why introduce TDD into an existing, functioning team?
What if the team is already having success with their current process? Why add something so different as TDD and risk potentially screwing everything up? Bill touched on this in his post, but I’d like to expound upon his point. His point was essentially: Is it really working, or does it just appear to work? Shipping software is not the only metric. Is what they’re shipping as high quality as it could be? Could they ship faster? Are they working as efficiently on the code as they could be, or is a large percentage of their time spent on up-front design, bug reproduction and resolution, and other otherwise-avoidable activities? The first thought that came to mind is: Sure, you may have a bunch of heroes on your team that, through blood and sweat manage to pull off successful releases, but at what cost?
I get this a lot when talking to people about TDD. I hear things like, “But our process is working great, we’re shipping software on time and customers are happy!” That’s wonderful and I applaud your success. So now that you’re making customers happy, could you be making them happier? Could you be saving your company money by making your successes even more efficient? Let’s take it to the next level! Let’s make customers ECSTATIC! One vision that comes to my mind when people say they are having ‘success’ is a circus performer juggling balls in the air while riding a unicycle. Sure, that performer is an amazing expert in his field and extremely talented. However, if his task is to deliver the balls to a customer, he’s spending way too much effort when he could just walk them over to their destination. Are the talented experts on your team juggling on unicycles, or are they taking the easiest, shortest path? Which delivery method will make the customer more successful? Juggling my impress them, but it’s not really helping them.
On the other hand, I have seen teams (yes, including teams I’ve been on and even lead — I’m as guilty of this as anyone!) declaring success, but when probed for more details, it turns out that the customers don’t necessarily share the same enthusiasm for the success as the development team does. Many times, in this situation, if you ask customers how they really feel, they may say that quality is ‘acceptable’ or ‘good enough’ or ‘I can work around the problems’. I will ask the development team what metrics they’re using for measuring success (and the sustainability of that success), quality, efficiency, etc. Very frequently there is no answer, or everyone stares at their shoes. We can ALWAYS do better. We can ALWAYS improve and eek out more efficiency, more automation, more clarity, and, most importantly, more success for our customers. We should be relentlessly seeking out these opportunities and taking whatever reasonable risks we can to make sure that we’re not missing things.
In my mind, TDD is more than just a coding practice, it institutes this culture of relentless self-examination and improvement — a culture of quality, measurement, sustainability, and repeatability (all summed into the word I use a lot: ‘maintainability’). TDD is the tip of the iceberg, but it is supported by other good practices such as Source Control, Continuous Integration, Automation, and Code Refactoring — among many others.
Second Question: What’s the best way to go about introducing it?
So, how does one go about bringing this culture to their organization. Given that I propose that TDD is the tip of a cultural iceberg within your organization, the key is to change the culture and the focus of your team back to quality and customer satisfaction and away from merely shipping the software. OK, OK, I know some of you are going to slam me and say that ‘here those TDD guys go again…’ Yes, shipping is important. Shipping is critical, Shipping is one of the most important features of your project. There, I said it. But I’m also concerned that what’s being shipped is going to make the customer’s happy. And I’d even lean towards the side of ensuring customer satisfaction over hitting imaginary deadlines. Real deadlines (i.e. the money’s going to run out, we have a legal requirement to implement X by such-and-such date, etc) are a different story, but the values are still very similar.
Anyhow, on to the meat. Here’s one possible recipe for implementing a culture of quality and customer satisfaction in your development team:
- Get source control setup if you don’t have it already. Note: this can be the hardest step sometimes.
- Encourage frequent source control commits and the taking of source control seriously — not just infrequent code backups
- Get NAnt, MSBuild, Rake or FinalBuilder and automate the build. I’ve never met anyone who resisted this.
- Set up CruiseControl.NET/TeamCity and get CI going with your new automated build.
- Slowly encourage developers to install the CCTray or TeamCity agent tray thingee and encourage them to take build failures seriously. Eventually they will get the build-failure-fever and work to prevent it from happening.
- Add in a few unit tests to the build, preferably things that won’t break easily to give positive feelings about there being some tests in the build that pass consistently.
- Encourage people to add tests whenever they find a bug to ensure that the bug won’t happen again. This is usually an easy sell as doing the test as a repro case helps fix the bug faster.
- Eventually add a few tests that are brittle to get people used to caring when the build breaks due to tests. Then use that opportunity to discuss the best way to write tests in your environment.
- Pick a few of the developers who are most interested and/or who have the best attitude and introduce them to the TDD concept and do a short ping-pong pairing session with them on a simple feature to win a quick success.
- Keep doing more of #9 until someone else gets it and wants to help.
- Start doing more and more until it catches on throughout the whole (or most of the) team.
Third Question: Won’t this just add a bunch of time to my process?
This one is easy. In my experience, these practices pay for themselves rather quickly. The ROI on ‘sharpening your saw’ is usually very quick. An ounce of prevention is worth a pound of cure, after all. There is a startup cost, to be sure, but as long as you focus on the values and principles and ditch what doesn’t work and try what you think might work and constantly re-evaluate your practices, you will quickly shake out a set of practices that are right for your team and amount to force multipliers.