I was intrigued and a little disappointed to see Martin Flower’s thread on the value (or lack of) test-driven development. Meanwhile, I am watching enterprises with relatively weak strategies around testing struggle with Continuous Integration. It's a dark day for test people.
We all know testing is hard thing. I have seen time and again folks implementing “unit” tests that are really integration tests, mostly because they do not know how to write stubs, or use Interfaces and mocks. And I do agree that test driven development can lead to poor design decisions, perhaps most often that happens when architectures are weak to begin with.
Is testing dead?
So a little refresher just so we are all talking the same language. A “unit” is the smallest block of code with a deterministic input that produces a deterministic output. A “unit test” attempts to validate only the unit of code, passing deterministic values and expecting a knowable outcome. Very little code lives on an island, so most often there are components of the unit which interact with other units. Now here is the point: a proper unit test assumes these dependent objects to be valid.
If you are able to design tests, and you’ve mapped tests to use cases and use cases to development objects, then you have a nuclear capability that can forever be used to prove the validity of code implemented for a particular use case, assuming the case remains constant. So once we have beat upon the developers to properly test their stuff, the next problem with test driven design is that use cases are never constant. To me, this is a far graver concern than good unit test Hygiene.
Because use cases blow with the wind at the whim of the business (or the developer divining the intent of the business using rune stones), the next gap is implementing proper change control over use cases, along with a workflow that updates the existing set of tests to match the new usage. We have the tools to do proper unit testing today. MVC, MVVM, etch do an adequate job, it is just left to the developer to leverage the capabilities of the patterns. Good use case diligence is the concern of the entire team. If you have this, then I think the problems with test driven development fade quickly.
This also goes for black-box testing. I hear people tell me they can’t automate testing because the input range is so diverse. I don’t buy that. Of you are doing black box testing, then you have the ability to save the artifacts you tested with and bind them to the use case, story card whatever you’re using.
Fowler was spot on when he introduced us to continuous integration. We are just beginning to tackle the hard problems of enterprise development (dependency management) that can make it a reality. Let’s not run away from a good thing just because it’s hard. Let’s do these hard things because that is what it takes to build far more resilient systems with increasingly complex interaction models over time. That’s what John F. Kennedy would do, had he been a modern geek.