If you do Test Driven Development all the time, you’re doing something wrong

I’m a big fan of Test Driven Development, and even more of a fan of Behaviour Driven Development. So it makes me sad to see really great developers adopt these techniques a bit too dogmatically.

Most developers operate in two modes when they’re writing code. Test driven development helps amazingly with only one of them. Use it for the alternative and you’ll quickly become frustrated, hate TDD and never use it again.

What are these modes? Experimentation and, what I call Focused mode.

Experimentation mode’s main objective is learning. It might involve poking at a library, tool, language or framework to understand how it works, how to interact with it, and perhaps understand some of its limitations. You might learn how to configure it, how to deploy it, and even how to test it. If you write code, it usually is throw away code because you don’t apply the same level of code quality because it stops you learning about things quickly. When people apply TDD during this mode, the first normal hurdle is they don’t know where they should be test driving it because they haven’t learned where the cost-benefits payback lies. They spend a long time writing their test only to find out the thing they’re doing won’t work in that way and then sulk over the time spent writing the test.

Focused mode’s main objective is producing something that will be put into production, used by people and extended upon. Here you want to write just enough code to provide the correct functionality. This is the most ideal time to apply TDD. You care about the quality of the code you produce here.

Recognise what mode you’re operating in, and understand where to apply (and where not to apply) TDD to get maximum benefits. In short, avoid TDD during experimentation and use it when you’re focused.

17 comments

  1. Henk

    On the other hand, when I’m in experimenting mode, I find myself using more and more using unit tests. If a test fails, that means I probably misunderstood something. Whenever I find out that things “don’t work that way”, I change the assertions and leave the test in as a warning.

    When I’m satisfied I’ve learned enough, this leaves me with a great set of sample code.

  2. Kerry Buckley

    Not forgetting, of course, to throw away your experimental code, rather than succumbing to the temptation to “just add some tests” and use it for production.

  3. tony

    I also use unit tests when I’m in experimentation mode, I call it spike mode and often name my class or tests spike. I use the assertions similar to how i also use system.out.println to see the results of my experiment.

    I wouldn’t call that using test driven development all the time, rather more like using junit as one of my tools when experimenting.

    When I do test driven development, I also use a code coverage tool to ensure I’ve got 100% coverage, I never check coverage when doing experimenting / spiking.

  4. Pingback: links for 2008-02-06 | Lazycoder
  5. Brian

    Experimentation is formalized in XP as a “spike”. While I agree with some of the earlier posts that even during a spike I find tests help me define the parameters of the experiment you have a good point about “throw away” code and the fact that tests aren’t absolutely required in that stage.

  6. Pingback: James Carr » Blog Archive » links for 2008-02-08
  7. Nos Doughty

    I have always recognized these two modes, what I call ‘Exploratory Mode’ and ‘Grind Mode’. There is also ‘Investigation Mode’ (bug-hunting or maintenance) which (for very disciplined team members) benefits greatly from TDD as each assumption of the code is put under test. This allows for a good discussion with the BA’s about the failure conditions (edge cases they may not have considered) and serves as test harness to verify the patched codes impact on the system.

    However, getting programmers to try TDD can be a big difficulty. Basically, you are asking them to do double the work (at least) to finish each job. Now this does not take into account that TDD is not the same as ‘unit testing’ as more complex designs can be built as each layer of the solution is built and tested to be built upon. The problem is that ‘Joe Developer’ isn’t interested in building code of this quality, he’s going to be using unit testing to ‘prove’ his code works so he can say ‘hey, my unit tests worked.’

    I have not yet managed to convince anyone who is not interested in that degree of quality of the benefits of TDD. Also, these are the programmers who will be tempted to use the exploratory code as production code, rather then taking a good look over it and trying to recode it in a more efficient manner.

    Lets face it, theres usually a big difference between developers who started before the .com era when being a developer was a geeky job and was learned in the Maths faculty, and those who did IT degrees in the business faculty and are strictly 9-5ers… who are looking to just get by on the minimum amount of work required.

  8. Artem Marchenko

    I am also in the camp of those who use test frameworks during the Experimentation phase. And I also wouldn’t call it test-driven development.

    During Experimentation a test harness is just a nice place to put my code to and also it is easy to extract small sub-experiments into the separate “tests”.

    Though I might be biased, because my platform used to be Symbian, where it is quite difficult to write “just an experiment” without supporting framework.

  9. Phil

    _why agrees:

    Perhaps this is why I have trouble swallowing unit testing or extreme programming or other best practices as the law. I guess there’s a place for these tricks (the work place,) but they do not speak to the pure form of hacking for hacking’s sake, which I so ardently defend! Unit testing, in particular, is designed to reel in spontaneous hacking. It is like framing a picture before it has been painted. Hacking, at heart, will continue to be something of spontaneous order, something of anarchy, and the landscape of hacking is something which comes from human action but is not of human design.

    http://hackety.org/2007/12/24/thisHackWasNotProperlyPlanned.html

  10. Pingback: Using test guided techniques for spiking at Mark Needham
  11. Pingback: thekua.com@work » Controlling Time: How to deal with infinity
  12. Pingback: Why one should not live without tests « Dahlia Bock
  13. Curtis Cooley

    If you are new to TDD, this is good advice. As a novice, it is often best to apply a new technique only when it is optimal to do so. As you get better and begin to master the technique, you will find other places to apply it.

    I apply TDD as often as I feel it fits. Sometimes when I’m spiking, unit tests help, sometimes they don’t.

    And of course, please do not forget that TDD is a design activity not a testing activity. Of course you would not TDD a spike because you are not designing. When writing production code, you want to TDD because you want the design to be the best it can be given the knowledge of the system you currently have.

  14. Thommy B

    Love the post! Many things are like this, there is no ONE WAY of doing things all the time. Context matters.

    Thanks for sharing!

  15. Pingback: thekua.com@work » We do “TDD”. Oh really?
  16. Pingback: When is it OK to not TDD? | Atomic Spin

Leave a Reply