01.31.08

TDD – Design or Development?

Posted in TDD at 11:37 am by Pablosan

Those of you who have sat through my classroom training already know my thoughts on this, but I thought I’d do a bit of research along with giving my opinion here on my blog.

According to the Wikipedia (one of my favorite places, as you’ve probably already surmised) refers to TDD as “Test-driven development”: Scott Ambler (a link to his blog can be found in the sidebar) refers to TDD as “Test Driven Design”. Oddly enough, Scott references two authers, Kent Beck and David Astels, who both refer to the practice in their book titles as “Test-Driven Development.” So which is it? Well, both… but with a preference for Test-Driven Design, in my opinion.

While TDD is an incredibly powerful software engineering practice, the terminology is bothersome. First, because of word order the initialism (no, it is not an acronym because it is not pronounceable, and now you know where I stand in yet another debate… along with my stance on parenthetical statements) emphasizes testing. Second, when “Development” is used instead of “Design”, the primary benefit of TDD is missing entirely.

TDD is, first and foremost, a design discipline. By first writing a failing test, the developer describes the system’s expected behavior before writing production code. Because we are writing code in very small chunks – just enough to get a failing test to pass – a loosely-coupled, simple design naturally emerges. No, it is not foolproof, but it should at the very least “feel funny” attempting to over-engineer a solution when using TDD.

Secondly, TDD is a documentation discipline. TDD used in combination with descriptive naming of variables, methods, classes, etc. results in self-documenting code. This approach nearly eliminates the need for static documentation (comments): documentation that grows stale very quickly. What is worse than undocumented code? Inaccurately documented code! The tests written using TDD become dynamic, accurate, expressive documentation of the code under test. As Uncle Bob puts it, this form of documentation is “so expressive it actually executes!”

Finally, TDD is a testing discipline. The tests can be run continually, over time, to insure the code continues to behave as the developer has specified in the test. If code behavior needs to change, it’s accompanying test will have to change first followed by the production code change, so that production code remains properly validated.

So, calling the practice TDD puts the em-PHA-sis on the wrong syll-AH-ble. Changing “Development” to “Design” partially addresses the issue, but “Test” is still the first thing you see. This is not a heinous crime, but what if it could be overcome? It can. Stay tuned…

01.24.08

Flip the Switch!

Posted in Agile, Iterative Development, TDD at 9:37 pm by Pablosan

Everything is in place. We have fuel, we have mass, and we have gravity. It’s time to see the nuclear furnace in action! Ladies and Gentlemen, we have fusion!

From the Wikipedia: “nuclear fusion is the process by which multiple atomic particles join together to form a heavier nucleus. It is accompanied by the release or absorption of energy.” Hydrogen goes in: Helium and Lithium come out (see Hydrogen fusion). Helium goes in: Carbon and Oxygen come out (see Helium fusion). Carbon goes in: Sodium and Neon come out (see Carbon fusion). And so the process goes, converting simpler elements into heavier elements.

Not all stars make it into the upper stages. In fact, our sun is not massive enough to pass beyond the initial Hydrogen fusion stage. The more massive the star, the further up the chain it goes, but they all start with Hydrogen fusion and fusion is the heart of any star. Fusion is what takes the input and, in a controlled way, creates ever more complex output: much like the process of writing code.

The fusion process is governed by a set of fairly rigid rules. We have come a long way in describing those rules, much of which we have codified into a set of mathematical equations. These equations have become a sort of documentation, explaining what sort of output we can expect given a set of inputs. In fact, this documentation is so well formed that it actually executes – astronomers are able to examine a star and know how it will act because of these equations… this documentation.

In an Agile software development environment, we see the same interaction between a system and it’s rules when examining the practice of Test-Driven Design (or Development, depending on who you talk to). The good news is that the rules for TDD are much simpler and far fewer. In fact, there are only three rules:

1. Never write any code until there is a failing test (and a test that won’t compile is considered a failing test).
2. Only write the minimum amount of code that will cause the test to pass.
3. Examine both the test and the code for refactoring opportunities.

These rules are followed in a very tight cycle. One iteration through them should be measured in minutes (generally no more than ten minutes per iteration) and sometimes in seconds. For an engineer experienced in TDD, a cycle lasts about 90 seconds.

By following these rules:

  • software can be developed in a consistent, repeatable manner,
  • the design can emerge – meaning that the system will be neither under-engineered nor over-engineered, and
  • the resulting code becomes well documented (the tests become your documentation) – it is defined to the extent that it actually executes!


There are many positive side effects of the TDD process, much like the side effects of photons and gamma rays from the nuclear fusion in a star. The process forces the developer to describe what they want the system to do before coding it, resulting in code accuracy. Since the tests are very small, the resulting code is very small, encouraging solid design principles like single responsibility and small, concise components/classes/methods. Because the process is started by describing code behavior, it is natural for class names, method names and variable names to be named in such a way as to communicate the intended behavior; resulting in code that is largely self-documenting; resulting in fewer static comments that quickly grow stale.

The above is really just scratching the surface of what TDD can provide. Refactoring with TDD can become a disciplined and methodical process, as opposed to the standard cross-your-fingers-and-hope-nothing-broke approach. These, and many other reasons, are why I believe the interplay of code and test is the process at the heart of an agile project – it is the project’s fusion.

Does this mean that TDD is the most important of the four core Agile practices? I don’t think so. In fact, I think it would be difficult to prioritize the four principles I have outlined, as they are all central practices to establishing a solid Agile approach to software development. Through mentoring teams as they seek to transition to Agile, I have observed that maintaining balance between these core principles – Very Short Cycles, Self-Organizing Teams, The Planning Game, and TDD – is critical to the project’s success.

How does TDD fit in with Agile’s four core values? It very clearly aligns with “Working software over comprehensive documentation” and “Responding to change over following a plan.”

So there you have it: the slightly-modified, Uncle Bob version of the four core Agile principles. Having finished this exercise, I’m not convinced I will be sticking with this list. While it could be considered a part of “Self-Organizing Teams”, I think “Customer Collaboration” needs to be explicitly in the list. I am consistently seeing the lack of customer involvement derailing teams that are otherwise doing well with their Agile approach, but that is a topic for another time.