wnoise comments on Coding Rationally - Test Driven Development - Less Wrong

25 Post author: DSimon 01 October 2010 03:20PM

You are viewing a comment permalink. View the original post to see all comments and the full post content.

Comments (82)

You are viewing a single comment's thread. Show more comments above.

Comment author: Morendil 03 October 2010 04:37:07PM *  4 points [-]

We may have different understandings of "TDD", so I suggest tabooing the term. Can you address your argument above to the description that follows?

The process I know as TDD consists of specifyfing the actual values of a precondition and a postcondition, prior to writing the third (command) portion of a Hoare triple. The "rules" of this process are

  • I am only allowed to write a Command (C) after writing its pre- and post-conditions (P+Q)
  • I must observe a postcondition failure before writing C
  • I must write the simplest, "wrongest" possible C that satisfies P+Q
  • I must next write the simplest P+Q that shows a deficiency in my code
  • my algorithm should arise as a sequence of such Cs satisfying P+Qs
  • my application code (and ideally test code) should be well-factored at all times

If you follow this process strictly, you can't even begin writing a huge test harness. The process enforces interleaved writing of application code and test code. As I've argued elsewhere, it tends to counter confirmation bias in testing, and it produces a comprehensive suite of unit tests as a by-product. It encourages separation of concerns which is widely regarded as a cornerstone of appropriate design.

Empirically, my observations are that this process reliably results in higher developer productivity, by decreasing across the board the time between introducing a new defect and detecting that defect, which has a huge impact on the total time spent fixing defects. The exceptions to this rule are when developers are too unskilled to produce code that works by intention to start with, i.e. developers of the "tweak it until it seems to work" variety.

Comment author: wnoise 03 October 2010 08:09:17PM *  3 points [-]

Thank you for the quite clear specification of what you mean by TDD.

Personally, I love unit tests, and think having lots of them is wonderful. But this methodology is an excessive use of them. It's quite common to both write overly complex code and to write overly general code when that generalization will never be needed. I understand why this method pushes against that, and approve. Never the less, dogmatically writing the "wrongest possible" code is generally a huge waste of time. Going through this sort of process can help one learn to see what's vital and not, but once the lesson has been internalized, following the practice is sub-optimal.

Every bug that is found should have a unit test written. There are common blind-spots that programmers make[*], and this catches any repeats. Often these are ones that even following your version of TDD (or any) won't catch. You still need to think of the bad cases to catch them, either via tests, or just writing correct code in the first place.

[*]: Boundary conditions are a common case, where code works just fine for everywhere in the middle of an expected range, but fails at the ends.