Comparison: DbC and TDD – Part 2

This blog post is a continuation of the comparison and differentiation between DbC and TDD. Please take a look at part 1 which covers the design aspect (and shortly specification again which has been discussed in more detail here). Today’s post takes a look at documentation and code coupling and shows commonalities and differences of TDD and DbC towards these aspects.

Documentation

One important thing for other developers to understand your code is documentation. Code comments are a first necessity here to basically explain what a code component is intended to do. But comments have the unpleasant habit to run out-of-sync with the real code if you are not carefully and consequently adapting them. Most of all if you write obligations or benefits into comments there will be no check if those requirements hold or if the real implementation matches them.

DbC with its contracts is a much better way to document those specification aspects. Contracts are coupled to the code and e.g. with Code Contracts you get static and runtime checking for them. This checked documentation makes DbC really powerful (if properly used) and avoids the asynchronicity between code and documentation. It shows developers how a component should be used, what requirements the client  has to fulfill and what he can expect in return. The client can rely on these specified qualities which improves the reusability of contracted code components. Furthermore there are possibilities to integrate Code Contracts into the Sandcastle documentation and for Visual Studio 2010 there will be an add-in that immediately shows defined contracts on a component as you develop against it. With that you get great MSDN-like documentation that contains the defined contracts as well as support for your development process when you use contracted code.

Tests in terms of TDD add another aspect of documentation. Due to their exemplary nature and their specification of an element’s behavior those tests are great to show a developer the intent of a code component and give him a guideline to its usage. Since tests can be run and validated in a reproducible way developers are able to rely on defined behaviors as well.

Together with documentation comes the aspect of intention revealing. And both TDD and DbC add some value here. Both express the developer’s intention with a certain component and show far beyond code comments and naming conventions what behavior a client can expect. Developers can use the component in these specified ways and don’t have to manually investigate the component’s implementation.

Code coupling

One drawback of TDD is the locational gap between the code implementation and the tests as specification and documentation source. For sure this has an advantage as well: the code logic isn’t polluted with the specification and thus it’s kept clean. But the disadvantages weigh heavier for me. If developers want to show how a component behaves they have to cross the gap and investigate the tests. This is difficult for developers who are not very familiar with TDD. Furthermore tests don’t give any support for client usage of a component. Of course they give usage examples, but developers can use and especially misuse a component in arbitrary ways. This can lead to serious problems (e.g. inconsistent states) if there are no other mechanisms to prohibit misusage.

DbC on the other side sets contracts directly on the implementation of a code component in place. Thus they have a declarative nature and extend the definition of a code component. Some realizations of DbC like Code Contracts in .NET have drawbacks since they set contracts imperatively into the code, but rewrite the code after compilation to set the contracts in the „right“ places. Thus Code Contracts break the uniformity principle (different semantics should be expressed through different syntax) and pollute the code logic in some way. Other realizations like the Eiffel language have contracts as keywords built into the language which makes a better choice in my opinion. Anyway contracts at the same place as the implementation avoids the drawbacks of a locational gap. And moreover DbC prevents misusage of a component. Contracts are dynamically checked at runtime or statically at compile time and fail early if requirements are not satisfied. That’s a very important concept because it expresses a clear behavior if something goes wrong (existence of a bug) and gives a clear contract for obligations and benefits that hold and are checked in client/supplier communication.

[To be continued…]

kick it on DotNetKicks.com

Code Contracts #8: Sandcastle integration

Release 1.2.20903 (4 Sep 2009) of Code Contracts comes with a nice integration of contracts on classes and methods into Sandcastle documentation! By this, Code Contracts achieve an important goal: real „checked documentation“. This short article gives an overview of how to get your Sandcastle installation to handle contracts.

1) Install Sandcastle (+DocProject)

At first, of course you need a valid Sandcastle installation. Just go to the Sandcastle project page, download the latest release and install it. I recommend installing DocProject for Sandcastle and HTML Help Workshop and Documentation as well. This gives you a nice Visual Studio integration for creating documentation by Sandcastle.

2) Patch Sandcastle with Code Contracts files

Code Contracts documentation syntax is currently not included in the Sandcastle project. In order to make Sandcastle aware of the Code Contracts documentation items, you have to patch the Sandcastle installation with the Code Contracts files. For this, there exists a folder „Sandcastle“ in the Code Contracts installation directory (default is „Program Files\Microsoft\Contracts\Sandcastle„), which contains a file „Sandcastle.zip„.

If you’ve installed Sandcastle from the MSI package, just copy the contents from the „msi\vs2005“ folder of the UIP file to the following location of your Sandcastle installation: „Program Files\Sandcastle\Presentation\vs2005\„. Now you’re done and ready to generate documentation for your contracts!

3) Set up your project

First, if you want to generate documentation for a project in Visual Studio, go to the project properties and in the „Build“ option pane, check the XML documentation file option:

Activate the "XML documentation file" option

Then, to get the contracts injected into the generated XML doc file, go to the „Code Contracts“ option pane and select both the Build a Contract Reference Assembly and the Emit contracts into XML doc file options:

Select generation of Code Contracts documentation

Now, when you build your project, first the documentation of your project’s components will be created as XML file and then the contracts documentation will be injected in the same file.

4) Create your documentation!

For demonstation purposes, I’ve generated a project (including a new solution) AccountExample in Visual Studio, which holds just one class Account. This example class contains some contracts and looks as follows:

/// <summary>
/// Represents an account, to which you can deposit and from which you can withdraw money.
/// </summary>
public class Account
{
    private float _balance;
    /// <summary>
    /// The current balance of the account.
    /// </summary>
    /// <value>The account's balance.</value>
    public float Balance
    {
        get { return _balance; }
        private set
        {
            Contract.Requires(value >= 0);
            _balance = value;
        }
    }

    [ContractInvariantMethod]
    protected void ClassInvariants()
    {
        Contract.Invariant(_balance >= 0);
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="Account"/> class.
    /// </summary>
    /// <param name="balanceInitial">The initial balance, which will be set.</param>
    public Account(float balanceInitial)
    {
        Contract.Requires(balanceInitial >= 0);
        Contract.Ensures(Balance == balanceInitial);

        Balance = balanceInitial;
    }

    /// <summary>
    /// Deposits the specified amount to the account.
    /// </summary>
    /// <param name="amount">The amount to deposit.</param>
    public void Deposit(float amount)
    {
        Contract.Requires(amount > 0);
        Contract.Ensures(Balance == (Contract.OldValue(Balance) + amount));

        Balance += amount;
    }

    /// <summary>
    /// Withdraws the specified amount from the account.
    /// </summary>
    /// <param name="amount">The amount to withdraw.</param>
    public void Withdraw(float amount)
    {
        Contract.Requires(amount > 0);
        Contract.Requires(amount <= Balance);
        Contract.Ensures(Balance == (Contract.OldValue(Balance) - amount));

        Balance -= amount;
    }
}

Moreover, I’ve added a new DocProject to my solution, where I’ve chosen the „AccountExample“ project for generating the documentation from. With that we’re ready to roll!

When building the whole solution, first the assembly of the „AccountExample“ project is built. In this step, the following XML documentation file is extracted as well (note the injected contract tags – requires, ensures and invariant):

<?xml version="1.0"?>
<doc>
  <assembly>
    <name>AccountExample</name>
  </assembly>
  <members>
    <member name="T:AccountExample.Account">
      <summary>
            Represents an account, to which you can deposit and from which you can withdraw money.
            </summary>
      <invariant>_balance >= 0</invariant>
    </member>
    <member name="M:AccountExample.Account.#ctor(System.Single)">
      <summary>
            Initializes a new instance of the <see cref="T:AccountExample.Account" /> class.
            </summary>
      <param name="balanceInitial">The initial balance, which will be set.</param>
      <requires>balanceInitial >= 0</requires>
      <ensures>Balance == balanceInitial</ensures>
    </member>
    <member name="M:AccountExample.Account.Deposit(System.Single)">
      <summary>
            Deposits the specified amount to the account.
            </summary>
      <param name="amount">The amount to deposit.</param>
      <requires>amount > 0</requires>
      <ensures>Balance == (Contract.OldValue(Balance) + amount)</ensures>
    </member>
    <member name="M:AccountExample.Account.Withdraw(System.Single)">
      <summary>
            Withdraws the specified amount from the account.
            </summary>
      <param name="amount">The amount to withdraw.</param>
      <requires>amount > 0</requires>
      <requires>amount <= Balance</requires>
      <ensures>Balance == (Contract.OldValue(Balance) - amount)</ensures>
    </member>
    <member name="P:AccountExample.Account.Balance">
      <summary>
            The current balance of the account.
            </summary>
      <value>The account's balance.</value>
      <setter>
        <requires>value >= 0</requires>
      </setter>
    </member>
  </members>
</doc>

In a second step of the build process, the DocProject generates the documentation for the „AccountExample“ project by taking its XML documentation file. When finished, we’ll have a nice CHM file with the documentation of our example project.

In this documentation we can see our contracts now. On class level, we have our invariant:

Class invariants in Sandcastle documentation

And on method (+properties) level, we get the pre- and postconditions:

Method contracts in Sandcastle documentation

Conclusion

As you can see, contracts in documentation are really valuable. Including them in Sandcastle documentation brings the claim of „checked documentation“ to life! This really helps other developers to understand the intent of your classes by looking at the documentation. And by automatically generating documentation out of your code-based contracts, you can be sure that docu and code do not run out of sync. This really puts more value on Code Contracts and is a real practical advantage!

kick it on DotNetKicks.com