locked
Code Contracts. RRS feed

  • Question

  • I heard about code contracts quite a while, but only now I've become interested in it. At first glance, it seems like a good thing, but I know nothing about the experience of anybody in using code contracts and I know nothing about the future of this part of .NET framework.

    So, I have a couple of questions:
    1. Is it true that, in general, TDD using say NUnit - an approach which fully covers all the features of the code contracts? Or is it two completely different concepts?
    2. What is your experience in code contracts using?
    3. What conclusions can you make about code contracts? Is it worth spending time on it?




    • Edited by EngineerSpock Sunday, February 19, 2012 7:18 AM
    • Moved by Paul Zhou Wednesday, February 22, 2012 6:58 AM move for better support (From:.NET Base Class Library)
    Sunday, February 19, 2012 7:15 AM

Answers

  • Hi,

    1. I believe there's some overlap between unit tests and Code Contracts, but neither covers the other entirely.  Furthermore, I don't believe that TDD and Design by Contract (DbC) are mutually exclusive paradigms.

      Unit testing as a tool for finding bugs is about regression testing and/or discovering code that doesn't meet certain requirements, which often includes business requirements as well as precondition contracts (only).  Unit tests exercise your code to make sure that it satifies your requirements, but often those requirements aren't stated except in the unit tests themselves; so essentially, it's the actual runtime behavior of the API and the unit tests together that define the expected contracts of the API.  As a tool for design (e.g., TDD), unit testing is about thinking in terms of the consumers of your APIs, which helps you to develop APIs that are easier and more appropriate for consumption with regards to particular requirements.  Note that there are secondary reasons for including unit testing as part of your development process (e.g., TDD) that aren't related to this discussion, such as encouraging designs with IoC, DI and loose coupling.

      In contrast, Code Contracts as a tool for finding bugs is not about regression testing or business requirements but is instead all about discovering code that violates explicitly stated conditions as early as possible.  Unlike unit tests, contracts are not often inferred by the actual runtime behavior of the API and the unit tests that exercise them, but are instead stated explicitly as preconditions, post-conditions and internal invariants.  This means finding most bugs at compile time (via automatic static checking), but often more importantly it means finding bugs at runtime (via instrumentation), which is something unit tests cannot do.  The idea is to have an application crash as soon as it violates some contract instead of lugging on until some later time when the consequences of bugs reveal themselves, at which point you'd be lucky if the app were to crash before corrupting user data.  As a tool for design (e.g. DbC), Code Contracts is about thinking in terms of the consumers of your APIs, just like with unit testing; however, Code Contracts includes post-conditions and internal invariants, which are not usually exercised by unit tests.  Furthermore, Code Contracts provides a static checker that evaluates your contracts at compile-time.

      Perhaps the overlap between unit tests and Code Contracts can be summed up as follows: Code Contracts allows you to place unit tests for public contracts directly into your code to be executed at runtime (i.e., preconditions).  By explicitly stating contracts in code, you don't have to depend upon the public contracts of an API merely being inferred by unit tests' assertions.
    2. My experience using Code Contracts has been very good.  I can't imagine developing without it anymore.  I find that Code Contracts has greatly improved my APIs and has enabled me to feel more confident in them.  It has helped me to track down many bugs during deployment, before deployment and even after deployment.  Design by Contract has helped me to understand the requirements of my APIs more easily and thoroughly than with unit testing alone.  (Full disclosure: I don't use TDD and I tend to only write unit tests as a regression-detection tool whenever I feel that its benefits outweigh its costs, which to me is certainly not "100% code coverage".)
    3. Yes, it's worth spending time on it even for the simplest of cases: instead of adding the legacy-style if...then...throws, add Contract.Requires.  With static checking enabled, you'll immediately benefit from using code contracts.

    - Dave


    http://davesexton.com/blog

    • Proposed as answer by Monsignor Wednesday, February 22, 2012 2:36 PM
    • Edited by Dave Sexton Wednesday, February 22, 2012 3:02 PM Fixed some spelling errors
    • Marked as answer by EngineerSpock Saturday, February 25, 2012 1:27 PM
    Wednesday, February 22, 2012 8:13 AM

All replies

  • You'll probably get better help at the Code Contracts forum: http://social.msdn.microsoft.com/Forums/en-US/codecontracts/threads

    Paulo Morgado

    Monday, February 20, 2012 1:50 AM
  • Hi,

    1. I believe there's some overlap between unit tests and Code Contracts, but neither covers the other entirely.  Furthermore, I don't believe that TDD and Design by Contract (DbC) are mutually exclusive paradigms.

      Unit testing as a tool for finding bugs is about regression testing and/or discovering code that doesn't meet certain requirements, which often includes business requirements as well as precondition contracts (only).  Unit tests exercise your code to make sure that it satifies your requirements, but often those requirements aren't stated except in the unit tests themselves; so essentially, it's the actual runtime behavior of the API and the unit tests together that define the expected contracts of the API.  As a tool for design (e.g., TDD), unit testing is about thinking in terms of the consumers of your APIs, which helps you to develop APIs that are easier and more appropriate for consumption with regards to particular requirements.  Note that there are secondary reasons for including unit testing as part of your development process (e.g., TDD) that aren't related to this discussion, such as encouraging designs with IoC, DI and loose coupling.

      In contrast, Code Contracts as a tool for finding bugs is not about regression testing or business requirements but is instead all about discovering code that violates explicitly stated conditions as early as possible.  Unlike unit tests, contracts are not often inferred by the actual runtime behavior of the API and the unit tests that exercise them, but are instead stated explicitly as preconditions, post-conditions and internal invariants.  This means finding most bugs at compile time (via automatic static checking), but often more importantly it means finding bugs at runtime (via instrumentation), which is something unit tests cannot do.  The idea is to have an application crash as soon as it violates some contract instead of lugging on until some later time when the consequences of bugs reveal themselves, at which point you'd be lucky if the app were to crash before corrupting user data.  As a tool for design (e.g. DbC), Code Contracts is about thinking in terms of the consumers of your APIs, just like with unit testing; however, Code Contracts includes post-conditions and internal invariants, which are not usually exercised by unit tests.  Furthermore, Code Contracts provides a static checker that evaluates your contracts at compile-time.

      Perhaps the overlap between unit tests and Code Contracts can be summed up as follows: Code Contracts allows you to place unit tests for public contracts directly into your code to be executed at runtime (i.e., preconditions).  By explicitly stating contracts in code, you don't have to depend upon the public contracts of an API merely being inferred by unit tests' assertions.
    2. My experience using Code Contracts has been very good.  I can't imagine developing without it anymore.  I find that Code Contracts has greatly improved my APIs and has enabled me to feel more confident in them.  It has helped me to track down many bugs during deployment, before deployment and even after deployment.  Design by Contract has helped me to understand the requirements of my APIs more easily and thoroughly than with unit testing alone.  (Full disclosure: I don't use TDD and I tend to only write unit tests as a regression-detection tool whenever I feel that its benefits outweigh its costs, which to me is certainly not "100% code coverage".)
    3. Yes, it's worth spending time on it even for the simplest of cases: instead of adding the legacy-style if...then...throws, add Contract.Requires.  With static checking enabled, you'll immediately benefit from using code contracts.

    - Dave


    http://davesexton.com/blog

    • Proposed as answer by Monsignor Wednesday, February 22, 2012 2:36 PM
    • Edited by Dave Sexton Wednesday, February 22, 2012 3:02 PM Fixed some spelling errors
    • Marked as answer by EngineerSpock Saturday, February 25, 2012 1:27 PM
    Wednesday, February 22, 2012 8:13 AM
  • I think one great point about CC (with static checking) when combined with TDD is that a lot of the smaller tests do not need to be written, in the same way that if you have a function "void Foo(int x) {...}", you don't need to write tests for what happens when you pass a string - it's forbidden by the language.

    This means you can focus on your tests which specify behaviour, which is much more worthwhile.

    Tuesday, February 28, 2012 9:50 PM