Test Driven Development and Design By Contract – friend or foe?

in this post i’ll try to answer a legitimate question, relating to a comment due to my last statement that interfaces are poor contracts: why do we need contracts (in the sense of invariants, pre- and postconditions) when we’ve got unit tests right at hand, that could also test the stated conditions?

in fact, it’s very tempting to see unit tests as an all-embracing instrument to check and show that a class will behave correctly, making contracts kind of unnecessary.
i’ll try to show you that unit tests (as an instrument for test driven development) and contracts (as an instrument for Design By Contract) indeed share the same goals but aren’t competing techniques, rather than methods that could complement each other.

it’s not about verification – it’s about specification

first of all, we have to clarify a potential misconception: unit tests as an instrument in the sense of Test Driven Development (TDD) aren’t that much about verification of a correct implementation rather than about a specification of how a unit should behave. in fact, it’s the specification (not the verification), that will drive development. you can see the comeback of this core idea in the rise of Behaviour Driven Development (BDD) that mainly tries to find an adequate vocabulary to write down specifications (that of course can be verified automatically) in an easy natural way, refocussing on how a component should behave under certain conditions.

on the other side, Design by Contract is also about specifying the design, in terms of the behaviour of your components. a contract asserts truths about the design of your code in the form of runtime tests placed within the contracted units itself. these assertions will be checked as the thread of execution passes through the parts of those components, and will fire if they don’t hold.

that said, both methods share the same main incitement – the specification of a system that will drive its design.

don’t bear away

as said, the goal of bdd is to reconcentrate on the specification of a component. the other way around, it means that it might be easy to loose direction within tdd, risking to set focus on testing and verification. i have to admit, that i walked into this trap more than one time in the past. of course the whole vocabulary (test, testcase, testsuite, …) makes you believe that it’s about testing. it’s easy to become addicted to this idea, so even writing tests after implementation seems pretty ok in this sense. that’s no longer possible if you see tests as specification: you firstly have to have a specification on what a component is intented to do – you can’t start with an implemenation until that specification exist.
is the same true for Design by Contract? is the contract metaphor misleading? of course you could also define your contract afterwards, so again development of a component isn’t driven by it’s specification. but the contract metaphor uses a more appropriate vocabulary. with invariants, pre- and postconditions it’s clearly about the specification of the intended behaviour – the risk of seeing a contract as tool for verification might be much lesser.

collaboration includes clients and supplier

there’s a special area, where contracts are able to provide real benefits in regard to unit tests: oftentimes unit tests specify only the behaviour of a component as a supplier, that means the test asserts mostly the stated effects (the postconditions of a method). that’s perfectly legal: most of the prospective clients may be unknown to the designer of the component or doesn’t exist yet. since the client is responsible for the adherence of preconditions it even should not be the in the job of the supplier.
a contract on the other side also specifies the constraints under which it’s legal to call a method (the precoditions). since contracts act on runtime, those preconditions will also be regarded when it comes to collaboration between an arbitrary client and the supplier component. the following points show some aspects of this holistic view:

reliance on a proper context

most developers (including me) tend to insert guard clauses in their code despite having unit tests. they don’t seem to trust about the context in which the method get’s called (that’s of course a good idea if the context can’t be foreseen). but you’ll even find this fact in environments, where the whole context is controlled by the same team. that may be also because of the before mentioned lack of knowledge about all clients that may call your component, especially in teams with limited communication. another one might be the local (specification / test in a different file than the component) and the temporal (tests at design time – collaboration at runtime) ‘distance’ between the code and the test.
having contracts aside the code (as part of the public interface of a component) you can rely on at runtime, seems to increase trustability in the running context. This may be because of …

support of defensive programming

with Design by Contract, contrats automatically protect methods from inproper usage, like illegal arguments (in the simplest case) in the real hard world, checking potentially a wider range of collaborations than a test ever can do (tests cannot show the absence of defects, it can only show that defects are present). like Bertrand Meyer said: a test checks one (or a limited set of) cases. a contract describes the abstract specification for all cases.
that said, preconditions that will work at runtime, making guard clauses in a way redundant, because the method can rely that it’s called in a proper way. that’s a runtime feature you can’t achive with unit tests. they could only check or specify how a component should behave if it’s called in an inproper way (for example by expecting to throw an exception, which becomes a postcondition). but this one wouldn’t free you to write additional guard clauses.

clear reliable documentation

while tests can be seen as an additional artifact that specifies the expected behaviour of a component, contracts form part of the public (client-) view of a class – they are part of the public interface. personally, i’m lazy – i want to recognize the core behaviour of a building block by looking at its interface / signature, not studying an amount of code be it the building block itself or a test – but of course there are also other preferences that prefer a split between specification and implementation.
of course those contracts are more than documentation, since assertions are checked at runtime, thereby testing that the stated contracts are consistent with what the routines actually do.

integration ‘tests’ for free

this one follows directly from the initial point, when regarding collaboration between clients and suppliers: having contracts that can be turned on and off makes it very easy to test and retest parts of a program. it allows you for instance to continue to test class A while you are working on class B, in case there are any interactions you did not foresee. of course, this is kind of integration ‘testing’ – it’s not about the specification of the behaviour of a single component but more about collaboration between a set of components and most of time not in the scope of unit tests.

clear Design

a contracts condition is an equivalent description of the algorithm used in a function, but written in an orthogonal manner, so thinking about such matters as pre-, postconditions and invariants help to make the concept of a class more explicit. it might encourage you to think about the conceptional model of a building block. that might lead to a clear design: obligations and benefits are shared between client and supplier and are clearly stated.
the limitations on the use of a method are clearly expressed and the consequences of calling it illegally are clear, so programmers are encouraged not to build routines that are too general, but to design classes with small single-purpose routines. while TDD guides you more towards loosely coupled building blocks (because it hurts when trying to test a tightly coupled component in isolation), DBC guides you more towards smaller building blocks with a clear resoponsibility (because it hurts to write invariants of classes with more than one responsibility or write pre- and postconditions for methods with more than one task).

‘debugging’

contracts can take part in ‘real life’, that means under real runtime conditions, maybe during development and user acceptance test – they take effect under real circumstances while ‘real’ clients (no mocks) and real collaborators (maybe also contracted) interoperate with each other. so contracts also guarding the collaboration of muliple building blocks forcing to fulfill a collective adduced goal due to a specification. having clear sound messages that state the cause of a contract violation, helps locating where the fault lies semantically: it’s very easy to find the reason of a misbehaviour within a specific interaction, pointing directly to it’s origin (if a precondition is violated, than it’s the fault of the client, if an invariant or a postcondition is violated, than it’s the fault of the supplier)

reuse

for library users (where tests may not be accessible), contracts clearly explain what library classes do and what constraints there are on using them. they provide feedback to someone learning to use other peoples classes: sometimes you only know the interface to operate with – the implementing class is unknown. having contracts on that interface gives you a clear, sound concept of the limitations and relevant effects in programming against that interface in a proper way.

open close principle compliance

while tests usually test a single unit, DBC handles inheritance in a broader way, supporting also inheritance of contracts to subclasses and therefore forcing to adhere to the claimed behaviour, stated in contracts of a superclass or interface. this goes hand in hand with the Liskov Substitution Principle.

conclusion

as you might have seen – Design by Contract is contributing some mind alluring features and ‘drivers’ when it comes to the specification of the intented behaviour of a component or even a whole system of interacting objects. as seen, contracts also regard the proper collaboration between clients and suppliers – a feature that’s mostly not in the scope of unit tests.
those new drivers fit very nicely with the strengths of unit tests (not all mentioned here), making them a perfect team for a ‘specification driven development’.

10 Responses to “Test Driven Development and Design By Contract – friend or foe?”

  1. TDD/BDD and Design by Contract: I don't really see any conflict between the two - Jeremy D. Miller -- The Shade Tree Developer Says:

    […] found an interesting link today from Mario Gleichmann called Test Driven Development and Design By Contract – friend or foe?.  I've always been lukewarm toward Design by Contract (DbC).  Occasionally […]

  2. Erkki Lindpere Says:

    I’m sure this might be an interesting post, but I’m not going to read it. Please learn to use capital letters properly — it might get you more readers.

  3. Dan Says:

    I’m not concerned about capital letters.

    What would be helpful though – are there books, tools or articles you recommend for DBC (especially when you are using Java and not Eiffel)?

    Can you show what some code looks like when it is implemented with DBC, contrasting it to the usual non-DBC approach with guards?

  4. Mario Gleichmann Says:

    Erkki,

    thanks for your free spoken feedback!

    I’ll try to take your suggestion to heart and use capital letters for future posts (let’s see how long i can stick to that).

    But than you have to read my posts constantly … ;o)

    Best Regards

    Mario

  5. Mario Gleichmann Says:

    Dan,

    unfortunately there are no books i’ve heard of, that adress DBC in Java.

    There are a few great books out there (to my knowledge), that cover the generall ideas behind DBC very well. In fact, some of the statements inside the post are highly influenced or taken and kind of ruminated from those books (and online articles).

    First, there is of course ‘Object-Oriented Software Construction’ by Bertrand Meyer, the ‘inventor’ of Design by Contract. This book’s not only about DBC (but a fair portion), but about the principles of OO (as the title says). I’m sure you already know this one.

    Secondly, there’s ‘Design by Contract, by Example’ by Richard Mitchell and Jim McKim. It’s mostly about the suggested six principles of sound contract design, embedded within examples.

    And of course, there are some good sources within the web! A good starting point may be some interviews with Betrand Meyer at artima, for example at http://www.artima.com/intv/contracts.html

    In my last post – why interfaces are poor contracts – i showed a simple example on how to annotate a java interface with a contract, using SpringContracts – a little solution for DBC in java. Of course there are some more good solutions for DBC in java – you may want to check one of them.

    Greetings

    Mario

  6. Ken DeLong Says:

    Nice article. What’s the leading framework(s) for DBC impl in Java these days?

    Also, how do you write class invariants for Spring/Hibernate style POJOs that aren’t initialized until they are all dependency-injected?

  7. Mario Gleichmann Says:

    Ken,

    honestly i have no idea which of the existing solutions is the leading one. there are some mature frameworks out there – you might take a look at contract4j, jcontracts or C4J.

    To your second question – i can only speak for SpringContracts: In this case SpringContracts relies on AspectJ-AOP (Spring-AOP won’t work here) and LoadTimeWeaving, using AspectJs weaving agent. With this tools on board, it’s no problem to even advice instances whose lifecycle is not controlled by Springs ApplicationContext but created by Hibernate for example.

    Greetings

    Mario

  8. Ilene Mcgee Says:

    dhanush phonasthenia maty monopolylogist unmeddle huddlement streckly overwake
    Shannon Cordoves – Jack Edson Realtors
    http://www.tsrnet.com/

  9. Malcolm Murphy Says:

    dhanush phonasthenia maty monopolylogist unmeddle huddlement streckly overwake
    Franklin County Library System
    http://www.nutritionoutreach.com

  10. One brike at a time » Blog Archive » Test Driven Development and Design by Contract Says:

    […] intersting articles on thus very subject: DbC and Testing, more on TDD vs Design by Contract and Test Driven Development and design by contract, friend or foe. On the other hand I did not find a tool that was satifsfying to link TDD and DbC (don’t you […]


Leave a comment