« You too can be a Management Consultant| Main | Note to Younger Self: Learn to Enjoy Exercise »

TDD: I Want to Believe

| | Comments (0)
poster of flying saucer over trees with caption I want to Believe


You'd think as an agile coach that I would be fervently advocating all things agile, but that's not the case.

Part of the problem is that agile is not part of a standards organization the way, say, Scrum is. So there's no hard and fast rule about whether something is or isn't agile. In general, agile is a marketing term that describes a lot of best practices that have developed in technology solutions over the past 40 years or so.

Some of the old stuff, like iterative and incremental development, are no-brainers. But some of the new stuff, like some of the XP practices, are tough to get your head around, especially if you're an old fart like me.

TDD is one of those things. TDD, or the idea that you design and code your tests before your code, seems like a nice idea. Kind of like a new religion that worships fruit loops. Perfectly harmless, and from all appearances, something that makes people happy and more productive.

TDD does a lot of great things, like promoting the idea you should only code what you need to get the job done, or the idea that if you write the test first, it forces you to think of your code design before you start coding. Or the beautiful fact that once you're done you should have total code coverage. Got a problem with all of that technical stuff involved with making software happen? An agile practitioner is most likely to say "Use TDD" TDD, it seems, will fix all kinds of code problems like nobody's business. It's like motherhood and apple pie. Who wouldn't want all of that?

The problem comes when you're the person who's supposed to start worshiping fruit loops. Then it ain't so benign anymore, and you're forced to take a serious look at whether this new fruit loop thing is really worthwhile.

I remember when I was writing a software package to create Sharepoint BCC XML files. During the beta, one of the people who signed up wrote me a glowing email. "This is great!" he said, "You've done a dynamite job here!"

We wrote some emails back and forth and he continued to rant on about how good the product was. Turns out he was a mentor/teacher in XP and .NET and was interested in writing something similar. He kept pressing me on how I developed that app so quickly, and finally I had to admit that I did NOT use TDD.

"I can't imagine how that could be," was his response, and I never heard from him again!

I might not be the sharpest knife in the drawer, but here are my reasons to doubt that TDD is the answer to all of today's coding problems:

  • Where are all of the TDD repeat teams?I have a simple rule: unless you are directly involved in coding, don't tell me what kinds of coding techniques are great and what kinds are bad. It's easy to write a book, easy to make a speech, or give a lecture. Life is short, and talk is cheap. Show me the money.

    I want to meet a team that got through with TDD on one project and are totally fired up about using it on another project. I want to see Bob, the best hacker in the shop, being the guy who uses TDD. I want real world, real life experiences, not somebody who wants to sell me something.

    So far? I haven't seen it. I think I've read one or two success stories about TDD on the net, and I've never met a real, live developer or team that were excited about using TDD for their next project.

  • Sometimes (most times) I don't want the minimal amount of code.TDD is a philosophy that you start with nothing and then develop the minimum amount of code necessary to meet the requirements of the user. But sometimes I don't want to do that. Perhaps I have multiple users, and I can only interview one. Or perhaps I believe that the solution is going to change quickly. There are lots of valid scenarios where I want to build a framework, or a system, or a Domain-Specific Language, or a Language-Oriented Solution to the problem at hand, not the exact bits and bytes for the user in front of me.

    I'm not saying to gold plate or over engineer everything you do, but there are lots of things you can do that require zero extra effort and provide maximum flexibility in the solution, like using an automated Data Abstraction Layer code-generating kit. You never mess with the generated code, and in return it gives you generic operations like init, load, save, serialize, etc for your business entities.

    Or maybe I have a framework I've decided to use. In order to use it, I might have to write all sorts of fat, bloated code. But I've made the decision that the trade-off is worth it.

    These are fine architectural decisions for an informed person to make. TDD takes that away from you.

  • How does that work in large teams with shared code bases? This is one of my favorites. Different people start differently and refactor differently. The thing that is a bad smell for me might not bother you at all, or vice-versa.

    So here I am factoring out my solution using functional programming techniques and Joe, across the hall, is working on adjacent code using imperative techniques. Joe isn't so good at functional stuff, and I'm not that hot on imperative coding. Sue and Steve are writing another piece and have decided to use a DSL, except parts of Joe and my code would have to be able to support a DSL for it to be used to maximum effect.

    You see where I'm going. People take the same original code and go different ways with it. The easy answer here might be "well, just communicate more", but I've never met anybody who communicated details of their programming style and re-factoring decisions to 7 other people on a real-time basis. Seems like there are a lot of scaling issues

  • Design is not for heroes.Doing a little design up-front is about 4 Cs, Communication, Collaboration, Consensus, and Coordination. Bad, Big Up-Front Design (BDUF) is about another C, Control. But when people through out all group design activities because Control never works, they miss out on all of the goodness of communicating, gaining consensus, collaborating, and coordinating who is doing what. They replace all of this agile goodness with one guy designing just as much as he needs for each little piece of incremental functionality he is deploying.

    Design is not a heroic activity. I know if feels really awesome to sit down at the terminal and be the guy who slowly solves the riddle of how to solve the user's problem, but if you're on a team of any size, it's not about you, dude. Everybody needs to understand the design trade-offs and strategies and everybody needs to participate in talking about patterns of behavior the team can expect from the code. If it's just me? Different story. Or even perhaps a second programmer might work well. But even then, you have to be careful that you are re-factoring in ways that do not break or majorly modify the conception that other people have of the end solution.

  • I want maximum refactorability.Speaking of re-factoring, I'd like to be able to do that as quickly as possible. In some cases, I might write exploratory code and re-factor a dozen times until I'm happy with what I've got. Will writing tests first help me write exploratory code better? I kind of doubt it.

    How about the case where I'm halfway through a project and I've ended up with a King Class that desperately needs slicing and dicing. Ugh -- that's going to be ugly to do in TDD. In general I want to put off testing until the minute the code runs through the happy path okay. Then as part of testing, I can try out various scenarios and paths in both my testing and coding strategy. Many times, by testing up front, I'm constraining myself not to re-factor, simply because I want to avoid the hassle.


picture of fruit loops cereal
All hail the power of fruit loops


A good friend of mine is an agile coach. He is a great PM, but hasn't coded in 20 years to my knowledge. So most of what he knows about programming comes from books or speakers.

He was telling me with pride the other day how another one of his clients finally got the TDD religion going, after only a year and a half! They had one team that made it through a project using TDD. None of the other teams at this large client wanted to participate.

And once he left, TDD fell by the wayside.

But he's very enthusiastic about how TDD will solve most all of the development problems teams have. To him, it's as close to a magic bullet as you can find. If nothing else, it makes for a great slogan -- "use TDD" -- instead of trying to understand the problem at a deeper level.

Oddly enough, he sees no irony in the fact that it took a year and a half to get one team using TDD. To him, that was just a problem with getting the organization to change. It had nothing to do with TDD.

Don't get me wrong -- I still think TDD has a lot going for it, probably in a mixed environment where some light high-level design is done "top-down" and then some low level design is done using TDD "bottom up" This seems like a nice compromise.

Do I think TDD is anywhere near the panacea that folks make it out to be? Sorry -- but I must have dropped the coolaid cup before I drank it. Call me a friendly skeptic. I'm just not sold yet. I'm willing to try it, to watch it tried, and to help make it successful.

I want to believe.

Leave a comment

About this Entry

This page contains a single entry by Daniel published on December 10, 2008 3:15 PM.

You too can be a Management Consultant was the previous entry in this blog.

Note to Younger Self: Learn to Enjoy Exercise is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Powered by Movable Type 4.23-en
Daniel Markham