Setting the bar higher with TDD

In order to play a little more with the new tools I've made use for Yapsy but also to experiment a little with TDD, I started a very small project, entirely hosted by github and for the development of which I tried to stick with TDD principles (more below).

iconThe project itself is called baciphacs and is nothing else than a new version of a piece of code that I seem to have to re-write each time I work in a new place: generate HTML code (with small bits of CSS embedded in tags) to represent a bar chart. This is arguable rarely the best way to draw charts but it often helps in drawing one quickly and without having to deal with questions about network reliability, licenses, and archiving.

Going back to TDD, baciphacs is surely a very bad example of if since it's just a first try, but it made it possible for me to confirm the impression I had about this method: it is actually counter-intuitive (which is quite well-known I think) but it puts forward design principles that are important to me and that go far beyond testing.

As a developer I guess we have a tendency to think about a program by starting to consider many minute (though important) details about its implementations with only a fuzzy idea of what would be its input and output data. Fuzzy ideas that are often made precise when we start testing the program. It's actually quite natural and in line with the parallel that The Mythical Man Month's F. Brooks draws between the activity of a developers and the fascination for puzzles.

But TDD, by forcing us to write tests before implementing a functionality, also forces us to think first and very precisely about the context in which the function or class will be used (which happens in what is called the "setup" by TDD terminology  zealots) and then to precisely write how it is called and used in terms of input, output and more generally API (this happens typically in the test itself) and all of this before dealing with the mechanics.

This forced reversal makes it possible to equilibrate a developer's personal priorities during the development which is certainly a good thing in the context of agile methodologies that put every developer "in charge" of both the design and implementation of functionalities.

One of the drawbacks still is that TDD pushes to spend a lot of time writing tests and going back and forth between testing and implementing. I'm ready to believe that the benefits (in short terms for quality and mid-term for development velocity) far exceeds any such drawback but still the immediate impression is "weird" (even when used to writing lots of tests).