A recent discussion has recently sparked up about whether or not can testing practices can be decoupled from design practices. Roy in his latest post "Unit Testing decoupled from Design == Adoption", has argued that one of the factor which prevents the masses from adopt AUT is the strong perception that AUT and design are strongly coupled, a perception which in his opinion is wrong. Udi on the other hand argues in "Unit Testing for Developers and Managers" that testing practices and design goes hand in hand.
So can Testing be decoupled from Design?
Well my answer is: Yes but probably not.
To clarify this cryptic answer I first need to put those practices in a context. As I see it, both design and testing are just means to reach an end. The ultimate goal is producing class A quality software. Software which brings real business value to its user/Customer. Most customers are completely indifferent to the system internal design, and are usually not that interested in how it was tested. They just wants a working reliable system which answer their needs.
Decoupling Testing from Design
As Roy I also believe that from a practical sense design and testing can be done independently. Too often have I heard managers and programmers alike claiming that they cant adopt AUT/TDD because that will lead to a major system rewrite(oops I meant redesign) and currently there is no time for that. This argument is just plain wrong (in today's world). Using the proper toolset the need to redesign the system can be decoupled from the technical problem of writing unit tests.
So My answer is yes one can decouple the technical need for redesign from the ability to write unit tests.
Testing and Design Correlation
However putting Design and Testing in the above context leads me to believe that both are just ways to achieve quality in a software system. In that aspect they cant be truly decoupled. Its like trying to decouple reading&writing skills from basic math skills, technically they can be decoupled but at the end if you want to get somewhere, you'll need to learn them both. No matter how hard that might be.
In fact My experience has shown me that both practices are mutually beneficial. Its easier and safer to redesign a system when you have a comprehensive set of tests as a safety net, and its much easier to write effective unit tests on a well designed system. Still one can redesign a system without automated tests (that how most people are doing it) and I have yet to see a system no matter had bad its design that wouldn't have a strong ROI for adding some test automaton.
However many times in this discussion I get the feeling that we are missing the real essence here, and the essence is the message that TDD approach brings. I have always felt (like many other) that TDD true innovation lies in its being a design practice. Unit testing and automation concepts were here long before the TDD, but only recently these practices took hold. In fact today trying to separate them in a discussion is well, kind of pointless. Too often I referred to AUT and people heard and understood TDD. There is something more to TDD then just writing
I think that Michael has captured the essence of TDD in his post: "The Flawed Theory Behind Unit Testing":
Unit testing does not improve quality just by catching errors at the unit level. And, integration testing does not improve quality just by catching errors at the integration level. The truth is more subtle than that. Quality is a function of thought and reflection - precise thought and reflection. That’s the magic. Techniques which reinforce that discipline invariably increase quality.
And that's how TD captures me, what makes TDD tick for me his the strong coupling between design and testing that it brings into my daily process. For me doing TDD is not just about writing unit tests. TDD is about investing time in thinking how the system should look writing tests to reflect those thoughts and refactoring the code to make it so.
so at the end follow Ian advise:
Make it work, then make it right.