This post originated from an RSS feed registered with .NET Buzz
by Udi Dahan.
Original Post: Unit testing hardly free
Feed Title: Udi Dahan - The Software Simplist
Feed URL: http://feeds.feedburner.com/UdiDahan-TheSoftwareSimplist
Feed Description: I am a software simplist. I make this beast of architecting, analysing, designing, developing, testing, managing, deploying software systems simple.
This blog is about how I do it.
The first was about TDD and the GUI, hosted by Philip Nelson where he set the tone by commenting on his experiences with MUCH decreased ROI when using TDD in the GUI. It was then that I began to feel that unit testing is really trying to be more than one thing.
(This isn't anything new, of course. From "unit tests", to "state-based tests", to "collaboration tests", going on to "integration tests" and "regression tests" we're writing the same style of code and running it with the same tools.)
It really hit home for me in the session I hosted with Mats about DI and IOC. When focusing on how DI changes the style of unit tests we write, Claudio mentioned that the example tests I was writing when not using DI were really state-based, and not unit tests. At first I thought, "oh, I should change that", but after taking another look, I realized that I really REALLY liked the similarity of state-based test code and use-cases/stories.
I realized that state-based tests are a lot more robust to changes than classic white-box unit testing or collaboration testing. This prevents situations (like the one Philip presented) from occuring. Unit tests aren't free, or that close to it, for that matter. Anytime you're refactoring an implementation of a class, or the way it collaborates with other roles, but aren't changing its interface, state-based tests won't break - your run-of-the-mill unit tests probably will. I know mine always did.
The final point that brought it all together for me, in light of Dan's thought-provoking Behavior-Driven-Development, was that state-based tests are really Behavior Specifications.
"This is how this class should behave."
And then the light bulb went off over my head.
These state-based tests really should be able to run on any class that implements this interface.
In essence, these "tests" are as much a part of the interface as the actual interface declaration. The interface is really just a static declaration of capabilities, whereas the behavior specification is the dynamic one. Both of them belong together, in the production code...