Wednesday, 7 October 2009

Dare to Question TDD?

I decided to write a quick follow up to my post yesterday. I made the following comment on this blog post:

TDD is a flawed paradigm by the very nature of having to write more lines of test code than production code. It has undoubted good side affects like higher quality code but nobody ever wants to discuss the flawed nature. Anybody who dares challenge it is slated as unprofessional:

Typically we get the same old cries of either being unprofessional or as is in this case is of Thomas Eyde we get the predictable cry of “You aren’t doing TDD” obviously. He posted the following quote:

You aren't doing TDD, obviously, because you don't want to use flawed methods. So how do you create your quality code? How do you verify your code does exactly what you intended it to do? How do you avoid to write code you don't need? How do you avoid to break working code when you apply your changes?

It is tedious for me to try and prove whether or not I do TDD, I can point to the horn tests as examples of the tests I have written. Anyway to get into such a debate is boring. For the record, I never once said you should not do it.

My question to the few people out there who may read this blog is a very simple one...

Why the hell can we not question TDD’s worth? Every time someone dares to question the flaws, they get slated as unprofessional.

The very fact that we end up writing more test code than production code makes me feel uneasy about the whole concept. TDD takes a very long time to get up to speed if you have no mentoring to accelerate the learning. The whole concept just seems loose with no clearly defined boundaries to help reign you into to a tighter feedback loop. For me, it took a while for the penny to drop with respect to how important it is to write a clearly defined failing test. I must stress clearly defined and not just a failing test.

TDD is flawed and instead of getting hot under the collar every time somebody dares to question it, we should be thinking of ways to improve the very loose and unguaranteed way the paradigm works. Of course I could just be very slow.

Or are we saying that we are totally happy with the experience and we will just leave it at that..................?


  1. I think people are currently in the "it's hot, so we HAVE to use it on everything!"-phase. TDD can be very useful, but sometimes it's not a great fit. Ayende wrote a post on this earlier:

    I think/feel BDD is a lot more applicable to common software development scenarios. pure unit testing is good for frameworks basically, where you need to verify the fine grained code.

  2. BDD makes more sense because most of the TDD examples seem to be directed at the class level or even worse the method level. BDD expands this out.

    We are still having to write a lot of code to get adequate coverage. A lot of this code is tedious. Better tooling could be explored. Initiatives like pex are interesting.

  3. The "Volume of Code" argument doesn't fly because:

    1) TDD helps surface duplication, therefore helping to reduce the amount of production code
    2) Typing isn't my coding bottleneck. Thinking, analyzing and designing is. (if it's debugging, I've taken a wrong turn).

    I don't always do TDD with unit tests, sometimes it's with more functional tests. Things like DbC also help with the code-as-specification issue.

    But test code is inherently different than production code. You can delete a test and it won't affect production.

  4. The "Volume of Code" is not so much an argument as an observation or smell that we are being wasteful.

    I think Dbc is quite exciting both for documenting intent and another of layer of safety on the compiler.

    Maybe the compiler could be further enhanced to do more.

  5. Or perhaps the compiler could be more open like it is in boo where you can add your own compiler steps in to the compilation pipeline.

  6. Yes that makes me uneasy about TDD too. I think TDD as a manner of focusing your mind on fine-grained requirements is a step in the right direction. It puts where we should go in clear focus

    How to improve on TDD?

    1) Write fine-grained tests
    2) Pass it through some sort of genetic algorithm AI-driven code generator

    Doesn't exist yet, but mark my words it will. Probably soon. Keeps the spirit of TDD, gets rid of the double-time.

  7. imho if your goal is to ship bug-free code then do the tdd dance. if your goal is to ship code as quickly as possible then don't use it.

    it's a time-and-place thing for me.

  8. I think it all boils down to technical debt. What you do not do now, you might have to retrofit later.

    If I am developing test first then I write only enough code to make the test pass. I am less likely to go off on "developer" tangents.

    I should have broken the problem down sufficiently enough to be able to write enough tests to reach my iteration targets.

    I also have a more maintainable codebase which is less resistant to change.

    I think writing bug-free code is not really the goal of TDD or at least not mine. It is more to have a fluid codebase that can react to the twist and turns ahead.