It’s A Good Idea But I Won’t Do It

A poster on LinkedIn wanted counter arguments in the comments to this

Let’s summarise:

  • Some code paths aren’t worth testing
  • Writing test up front is a big investment of time
  • Coverage statistics will generate a lot of unnecessary work
  • TDD means rewriting tests for unwritten code when requirements change

Wrong. Wrong. Wrong. Wrong.

Solved.

Ok. Let me be a bit more constructive. It looks like the poster thinks:

  • TDD involves writing a lot of tests up front
  • Code coverage is a goal of TDD
  • TDD helps us test code paths
  • TDD takes hours and reduces engineering time that could be spent on features

All of this is incorrect.

It’s probably true, however, to say that a unit test that cares about the colour of a pixel might be a bad unit test.

If you’re going to argue against a straw man of TDD, no wonder you don’t want to do it.

Let’s define how TDD is meant to work.

  • We know something we want to make
  • We consider the first observable increment towards that thing
  • We write ONE failing test
  • We write the minimum amount of code to make it pass
  • We consider the next increment
  • We write ANOTHER failing test
  • We write the next increment of code to make it pass
  • Then refactor as needed
  • Rinse and repeat

The tests are concerned with interesting observable behaviour, not code pathways. But the fact that we only write code that we’re interested in observing, means that we seldom write pathways that are unused.

There are reasons why gaming coverage to 100% is useful. However, coverage is largely the outcome of good TDD.

So does TDD represent an investment in time? Not really, if you know how to do it, then you can write a good test in a few seconds, see the code pass, and not have too much uncertainty about what the application might do if you try to run it.

With long-form development without tests, you’d slave away for some number of hours or minutes, creating a ton of code that MIGHT work, and then play with it manually in the application, hoping to try out all the pathways it has.

You’ll probably get it wrong.

You would possibly get it wrong with test first, but with a small test to test one minor tweak on the behaviour, probably only requiring one or two lines of code to make it pass, you’ll be immediately aware of where you made a mistake. You’ll have been checking your assumptions each step of the way, and you’ll be close enough to deployment from the point where your tests first started passing for reasons other than hard coding.

So, I’m afraid the counter arguments for TDD, in terms of costs and up front effort are based on the following:

Most people who object to TDD haven’t actually mastered it, and are complaining about their own misuse of it.

One comment

Leave a comment