Someone recently asked me on the OT mailing list about my experience with test-driven development (TDD). They were concerned that it seemed to advocate throwing away all the careful architectural design work we've been taught is a good thing, in favor of just attacking the problem piecemeal. Here was my response:
Disclaimer: I'm not an XP expert. I haven't read the XP literature. My only qualification to say anything about it is that I've been using it for a few months, and have noticed a difference in my satisfaction with the code I produce.
First of all, you have to ask yourself if you've been successful with your architecture-driven approach. If the answer is "yes", then why are you considering changing things? I find that XP's main feature seems to be "ruthless practicality", so if you've already got something that works, go with it.
Second, architecture is basically a set of pictures (and a lot of thinking) that you draw for guidance before you start coding. Nothing about that is incompatible with TDD. Get an idea of how you want to do something, then write the tests that assert that your design does it, then write the code that makes the tests pass.
One of the ways I've started to think about tests is as a way of expressing requirements. What I particularly like about that is that I'm expressing them in a highly precise, machine-readable, unambiguous language with which I am already familiar...C#.
Another thing to consider: designs done in the abstract are typically at a higher level than the API level. Or if they are at the API level, they rarely express pre- and post-conditions. Tests do both, so they really magnify your design documentation, bringing it to a lower level.
Now, it's true that traditional architecture and TDD tend to emphasize different things. Most people wind up doing architectures that attempt to abstract all the functionality you *might* need. TDD takes a more just-in-time approach, focusing on only writing the functionality you
*actually* need, *right now*. Of course, test-first can be done even for highly abstract requirements, and designs can be written to a set of practical requirements - so those facets are orthogonal. It's just that they tend not to be.
Both approaches have their place. I just find that I so rarely know exactly what my requirements before I start, that it's difficult to start with an abstract vision. A set of tests is also a set of use cases, and expressing them so formally (i.e. as C# code) allows me to work out details at the level I care about: the API design.