« Passion and Architecture | Main | Ruby on Rails not ready for prime time »

2008.07.26

[Test|Contract] Driven Development?

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:

  1. Their code base has nearly doubled in size (in theory, so have the number of bugs).
  2. 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.
  3. 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
  • Design emerges as a result of implementing code to satisfy tests.
  • More of a "bottom up" approach to system design.
  • More design upfront than TDD, indicative of a "top down" approach to 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
  • Good for isolated classes.
  • More difficult when classes collaborate with subsystems such as servlets which require mocking.
  • DBC is not a first class citizen in mainstream languages such as Java, so tools must be used.
  • Quick and simple to create contracts.
  • Unclear how DBC could be used to ensure database integrity.

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:

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d8341c9edc53ef00e553d6e13e8834

Listed below are links to weblogs that reference [Test|Contract] Driven Development?:

Comments

Feed You can follow this conversation by subscribing to the comment feed for this post.

What is your opinion on CDD's refactoring support? One of the things I like about TDD is if you make a major change, yet all your tests still pass, it gives you some degree of assurance you haven't broken anything.
I think you can get similar, if not more, levels of assurance for refactoring with CDD:
  • Pre-conditions and class invariants go further than xUnit tests where you are typically checking the output (post conditions)
  • Static analysis can be used before and after refactoring to give you more confidence that the system still hangs together, even where you haven't covered it with a test yet - this of course relies on making sure you have specified your contract in enough detail
Hi Gavin,
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 :-)

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been saved. Comments are moderated and will not appear until approved by the author. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Comments are moderated, and will not appear until the author has approved them.