Over the last one year, I have spent time pairing with various TDD practitioners trying to find their avatar (style or form) of TDD. I was curious to know, given a problem or story how do developers go about Designing (Object modeling in particular)? How do they come up with classes and their responsibility? Do people spend some time at the white board coming up with some high-level design or do they jump straight into writing tests. My understanding is that TDD itself does not force someone to jump straight into code (tests). Basically it takes the Test-First practice one step further saying write the test before you write production code and let the tests drive the development. A lot of people prefer to refer TDD as Test Driven Design. Essentially, let the tests drive the design. They believe that this will help them come up with the simplest possible design if used with Refactoring. It will also ensure that we do not end up over engineering or under engineering the solution. We do just enough based on today’s needs.
After having spent over 1 year pairing on the same problem with close to 22 TDD Practitioners (and hoping to pair with more), I have come to conclusion that there are various Avatars (forms or styles) of TDD. Also something else that I found interesting was: It is very clear to most of the people that testing results in better design. But it might not be so obvious that your approach to testing or the way you think about tests can result in quite different tests and hence its impact on the design.
I found the depending on your avatar of TDD, the end object design was quite different. The purpose of this experiment is not to prove which avatar is better. Like anything each avatar has its trade-offs. My interest is clearly to capture different avatars and try to categorize them. Also try to find the rationale behind the approach.
Broad Categorization of TDD Avatars:
Broadly we can classify the avatars of TDD into 2 categories:
In the outside-in category developers starts with a high-level functional test at a story or use case level and drills into the low-level unit tests as development continues. The objective of development is to make the high-level functional tests work. In other words developers start with Story tests1 or Business-facing team supporting tests and move towards Unit tests or Technology-facing programmer supporting tests. It turns out that these tests are heavily state-based tests.
In the inside-out category the developers take a story or use case, do some really high-level analysis & design. Possibly, also some level of object modeling in their heads or on a white board. This activity should take less than 15-30 mins. Once they internalize the story or use case, they start writing technology-facing programmer supporting tests to drive the design. Very quickly they start building the story bottom-up. The objective of development is to make all these low-level unit tests working all the time. These tests are heavily interaction-based tests. I have not really seen these tests evolve into high-level acceptance tests and hence the inside-out arrow in diagram 1.
It is important to note that these avatars are not mutually exclusive. TDD practitioners tend to jump back and forth. But on a given project, the system design is heavily influenced by one of the avatars and not so much by the combination.
Read the whole draft paper here: Avatars of TDD. Please note that this is work in progress. I would really appreciate your feedback.
At the Agile 2008 conference in Toronto, Bill Wake and I faciliatated a workshop on Styles of TDD (had to change the name from “Avatars of TDD”, based on feedback from people that most people don’t know the word Avatar). You can find a quick summary of the workshop here : http://agile2008toronto.pbwiki.com/Styles-of-TDD