Jeff's Blog

Musings about software development, Java, OO, agile, life, whatever.


Thursday, July 10, 2008 
Fine-Grained Incrementalism

Seeing a first-time demo of TDD, students inevitably ask, "do you really code that way?" The answer is yes, even after almost ten years of doing TDD.

They are of course asking, do I always code the simplest possible solution first, instead of just introducing the obvious solution, the one that I know I'm absolutely going to need in another five minutes? And the answer is still yes.

For example, when testing a container, the first test inquires whether or not it's empty:

assertEquals(0, container.size());
and the passing implementation is:
int size() {
   return 0;
}
The next test usually involves adding an element to the container and asserting its size (which is of course only part of the complete verification):
container.add(element);
assertEquals(1, container.size());
Yes, I know I need a [hash map|array list|linked list|etc] in about 5 minutes. I still code:
void add(T element) {
   count = 1;
}

int size() {
   return count;
}
Not even a ++. That comes from writing a subsequent, failing assertion.

I offer many reasons:

  • It helps deeply ingrain the notion of incrementalism, which is at the heart of agile
  • It allows sustaining the fail-first, red-green rhythm, and thus keeps you out of trouble more often
  • Similarly, it allows adhering to the rule that insists on green bars every ten (five) minutes
  • It forces the addition of more assertions
  • It keeps with the spirit of YAGNI--sometimes you don't end up needing what you think you will
This fine-grained incrementalism involves continual movement from the specific to the generalized: from hardcoded solutions to progressively-more-generalized solutions.

Fine-grained incrementalism is, as many things in software development, a tradeoff. It results in continual waste product, and thus a slower initial pace. A hardcoded value is discarded, and replaced with a counter, which too is soon discarded. But on the other side of this trade is the significant benefit of continual and consistent forward progress--"slow and steady wins the race."

For the new TDD practitioner, and for even experienced TDD practitioners, it is very tedious and annoying. Often, developers simply discard rigid adherence to the practice. For an experienced TDD developer, that's their prerogative, and I'll admit that I have done so at times too.

For everyone else, I think it's essential to first learn the value of something before discarding it. So I'll define my use of "experienced TDD developer" in the prior paragraph as "someone who has not done enough fine-grained incremental development to understand how it helps." Perhaps I'm slow--I still prefer to work this way.

A final justification (aka "the new thought" that entered my head this morning):

Yes, it's slower, tedious, and produces continual waste, particularly as you build the rudiments of a class. But these complaints are focused at the early minutes in the lifetime of a class--a fraction of the effort and struggle involved with maintaining it. There's a benefit I didn't explicitly mention above, and that's the ability to more easily and safely maintain a system, because of the increased number of assertion increments. The small amount of initial tedium is worth it.


Comments:
Even though the production code evolves slowly, and is continually reworked, expelling tiny bits of waste... The tests are real from the beginning. The simple minded, easy to get to solutions, prove that the test are right. These tests work and do their job while the production code evolves and gets more complex. It might seem like they slow you down in the beginning, but its these tests that keep you moving rapidly with confidence.

Jeff, you're not slow. You are the fastest I've seen.
 
Thanks James, I particularly like the part about "moving rapidly with confidence."

Hmm, someday I'd like to participate in a head-to-head speed-TDD challenge. Time to deliver is primary, but points would be taken off for insufficient tests, or inadequate refactoring.

Who else is fast?
 
Post a Comment

Links to this post:

Create a Link



<< Home

RSS Feed (XML)

Archives

February 2004   March 2004   May 2004   September 2004   October 2004   January 2005   February 2005   September 2005   October 2005   November 2005   December 2005   January 2006   February 2006   March 2006   June 2006   August 2006   January 2007   February 2007   March 2007   April 2007   September 2007   October 2007   November 2007   December 2007   January 2008   February 2008   March 2008   April 2008   May 2008   June 2008   July 2008  

This page is powered by Blogger. Isn't yours?