In my last post on Passion and Architecture, Eric quite reasonably asked why I think TDD and DBC are opposed?
Let me start by saying I've recently become interested in DBC again after moving office whereby I noticed my old, dog-eared copy of Object-Oriented Software Construction and thought to myself "Hey, what ever happened to that crazy Eiffel language with that cool DBC idea?".
I remembered that the central idea behind Design By Contract is that if there exists a mechanism of defining pre and post conditions and the state of class invariants, you can use static analysis to formally prove program correctness. Neat huh?
Well, not so much. The XP guys said this specification up front business may not be the simplest thing that can possibly work. Instead, you should focus on designing tests that express the system, then write code until the tests pass. The true architecture of the system will then emerge naturally, closely matching what the problem calls for, not some theoretical abstraction that has bits you won't need.
So we all converted to The Church of Agile.
Except...
People are now starting to look at their TDD projects and noticing that:
- Their code base has nearly doubled in size (in theory, so have the number of bugs).
- It is hard to quickly create (or run) meaningful tests beyond setters and getters, so either their velocity drops or tests are not being written at all.
- There is a great deal of code repetition in the tests.
CDD, on the other hand, pretty much has the same goals as TDD, but with benefits... You get to use the contract as part of your documentation, and you can do that static analysis thing to verify that your program will run correctly.
So back to the question: are TDD and CDD opposed?
My answer: an unequivocal "I'm not sure".
Here is how I break it down:
TDD | CDD | |
Design |
|
|
Refactoring | Implementation can change radically without impacting existing collaborating client classes | Same assurances as TDD |
Quality | "Testing can prove the presence of bugs, but not their absence" - E. Dijkstra. | Static analysis using formal verification to ensure quality is one of the main advantages of DBC. |
Ease of use |
|
|
At the end of the day, my instinct is telling me that while CDD could potentially do everything TDD does, the tool and first class language support could be a major stumbling block for using it as an outright replacement.
Further reading: here are some of the links I've come across in researching DBC that have shaped my thinking:
- InfoQ have a great video (skip to around the half way mark) of Jim Coplien and "Uncle Bob" Martin debating TDD & DBC.
- Testing and Language Design talks about how Python's doctest and DBC are quite similar, as well as giving TDD a good poke!
- Test Driven Development and Design By Contract - friend or foe? Lots of stuff in here that I haven't fully digested yet.
- Bertrand Myers compares Design By Contract to Test Driven Development, and thinks they may well be complementary.
Posted by: AustinWiltshire | 2008.07.26 at 11:12 AM
Posted by: Gavin Terrill | 2008.07.26 at 12:38 PM
The comment that you left on Kris' post led me to this post. Kris was actually responding to my post, where I was approaching a DBC standpoint.
It's interesting that the workshop we were running reached this stage by test driving the application. We did, in effect, evolve the contract.
I think that DBC and TDD / BDD can co-exist quite happily, and I'm also pleased that the contract is a contract as of our understanding at this point, and we reserve the right to change it :-)
Thanks for giving me more stuff to think on :-)
Posted by: Andy | 2008.08.12 at 02:41 PM