Thursday, August 30, 2007

Testing Will Challenge Your Conventions

I've just stumbled upon a fantastic blog post Testing Will Challenge Your Conventions, by Tim Ottinger. In it he lists a number of ways that doing TDD fundamentally changes the way you code:
  1. Interfaces suddenly seem like a good idea.
  2. You stop using singletons and static methods.
  3. Private makes less sense than it used to.
  4. You pass dependencies in the constructor (the so called 'fat constructor')
  5. Smaller methods are the norm.
  6. You read tests before the code; it better explains the intention.
  7. Usability trumps cleverness.
  8. Premature performance optimisation is bad (YAGNI)...
  9. ... but test performance is crucial.
  10. Dependency is bad; you avoid 'God classes' and 'global hubs'.
  11. 'Clever' is dead. 'Clever' is hard to refactor. 'Clever' is hard to isolate, hard to internalize, hard to phrase in tests.
  12. Your IDE is only good if it allows you to do quick write/build/test cycles.
As he says, all this stuff is good practice, but the genius of TDD is that it drives you to do it. It gives you your first excuse to write component oriented, highly cohesive, loosely coupled code. Without it, these good practices just seem like academic hot air, right up to the point that you discover your application is spaghetti. As I blogged recently, I've had an epiphany where, in my mind, two distinct concerns, TDD and component oriented architectures have merged. Although I've been interested in component architectures for a while they've always seemed to be quite heavyweight beasts, and to be honest, I've never used them for application development. In the case of the MS IComponent framework that was the right call, the benefits would have been outweighed by ugliness of the framework. But with a lightweight, non-intrusive, component framework like Castle Windsor it makes perfect sense. What's interesting though is that it's just another example of how I've been lead to better programming techniques simply by doing TDD. What started as an easier way of writing test harnesses has had more impact on my development as a programmer than any other practice I've adopted.


Dmitry Pavlov said...

Hi Mike,

The link you provided doesn't work. I've googled for working one. Interesting article but as all articles about TDD and other agile methodology practices it always assumes that we write the code from scratch. And it's easy to use TDD in such projects.

But.. that is not true in a half of cases. A lot of projects now are extensions for various frameworks. And it is really hard to keep our code completely covered with unit tests. One perfect demonstration of that kind of framework is Managed Package Framework from Visual Studio SDK. That does extremely hard apply eXP style of work on such projects.

Dmitry Pavlov

Mike Hadlow said...

Thanks for pointing out the error Dmitry. That'll teach me to write blog posts at 1am instead of going to bed!

I partially agree with what you say about writing code within the context of a framework such as the Visual Studio SDK, it is harder to code test first in the situation where you are basically researching the framework. However, with any framework, you are simply leveraging it to provide services for your application and the core application logic itself can still be written test first.

For example, my VS web service test tool WsdlWorks is written as a Visual Studio custom project type and has deep VS integration, but the core functionality: reading WSDL files, creating service proxies and example messages can still be written in a component oriented TDD style.