Documenting my journey through the pratice of software development RSS 2.0
 Wednesday, April 30, 2008

There's a lot of talk about Spec# in the blogosphere, recently.

I've read a few blog posts and reviewed some of the official web site, and it looks very promising. Essentially, it's a language extension to C# that adds Design By Contract as a 1st class part of the language - including non-nullable types, preconditions, post conditions, etc.

Looks like my DBCUnit idea may have a short life.

Wednesday, April 30, 2008 7:50:47 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | DBCUnit | Design By Contract

 Wednesday, April 23, 2008

Based on the proposed information and syntax from My Previous Post, I've created a basic Design By Contract unit testing framework. The intent of the code so far, is to provide a quick-and-dirty proof of concept. With that in mind, I give you

DBCUnit hosted on GoogleCode

You can get the source code via Subversion:

http://dbcunit.googlecode.com/svn/trunk/ 

Please note that the existing code only supports one assertion so far: Equals. Also, the execution engine is entirely made up of terrible code that assumes a lot of perfect-scenario input. I'm planning to flesh it out more and make the code more sustainable - actually adding Contract specifications for my execution engine, etc. Let me know what you think of the idea and the syntax. Also feel free to join the project and pitch in for syntax and implementation.

The one Contract I have specified so far, just to get rolling, is that a [PreCondition] should be executed once.

[Condition]
public class WhenPreConditionIsPresentInContractCondition
{
 
    private int preConditionExecutionCount = 0;
 
    [PreCondition]
    public void PreCondition()
    {
        preConditionExecutionCount += 1;
    }
 
    [PostCondition]
    public void ThePreConditionIsExecutedOnlyOnce()
    {
        Assert.That(preConditionExecutionCount).Equals(1);
    }
 
}

To run the test, run build the solution and run the DBCUnit.Console pointing to the DBCUnit.Contracts.dll, like this:

C:\...\> DBCUnit.Console.exe DBCUnit.Contracts.dll

If the test succeeds, there is currently no message printed to the console window. If it fails, it will write out a message saying what value it expected and what the value was. It's all very simplistic at this point, just a proof of concept. I also set up the DBCUnit.Console project to automatically start with the "DBCUnit.Contracts.dll" as the startup parameter, so you can step into the code via debugger and see it in action.

Have fun, and don't laugh too much. This is my first attempt at hacking together a unit testing framework.

Wednesday, April 23, 2008 7:50:08 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Agile | DBCUnit | Design By Contract | Test Driven Development | Unit Testing

There's a lot of talk about Design By Contract (DBC) out there in the development world. Various development languages have varying support for it, but more importantly various processes have various levels of support for it.

It seems, though, that the farther down the path of development we travel, the more important it is for us to consider DBC in the code that we write. Large projects with multiple developers are in great need of DBC. Projects that have publicly distributed API's are in even greater need of DBC. Even if you are working on a simple, one person project for yourself, and you are the only one that will ever use it's methods and objects, I'm willing to bet that you will forget about the assumptions that you are making when writing the methods and objects, at some point.

So where does this distinct need for DBC leave us, in the world of .NET (C#, VB, and the other "common" .NET languages)? We still need a way to enforce DBC, but our language of choice doesn't support it, natively. So we have two real choices (excluding DSL writing, and/or switching languages) - documentation (via code comments or written / published documentation) or Unit Tests.

Yes, that's right - Unit Tests are not just for testing, anymore. Or more correctly, the tests executed by unit testing are not just for the sake of testing. The intention is verify the pre and post conditions of a design-by-contract. Of course, I'm not the first one to suggest this. It's mentioned briefly in "Agile Principles, Patterns, and Practices in C#" by Robert C. Martin and countless other times as well.

I am propose a new unit testing framework. I know, I know... "not ANOTHER xUnit framework... *sigh* ". In this case, I am proposing a semantic change along with the mechanical (syntax) change, specifically for the purpose of introducing unit testing to a group of developers that may not believe in "Unit Testing".

As an example of my proposed syntax, in a file called "SomeContract.cs", this test code would exist:

[Conditional]
public class WhenSomeConditionIsMet
{
    
    SomeValue someValue;
 
    [PreCondition]
    public void PreCondition()
    {
        Setup.My.Inputs inputs = Here;
    }
 
    [Execution]
    public void Execution()
    {
        someValue = Execute.TheContract.With(inputs);
    }
 
 
    [PostCondition]
    public void ThenSomeOutputIsSomeValue()
    {
        Assert.That(someValue).Equals("Some Known Value");
    }
 
 
    [PostCondition]
    public void ThenSomeOutputIsSomeValue()
    {
        Assert.That(someValue).DoesNotEqual("Some Unknown Value");
    }
 
}

To make this proposed syntax easier to understand, I'm basing it on the NUnit style of using attributes, at the moment; but it doesn't have to be that way. There is almost a one to one translation between NUnit and this.

  1. The [Conditional] attribute is equivalent to [TestFixture]
  2. The [PreCondition] attribute is equivalent to [TestFixtureSetup]
  3. The [Execution] attribute is equivalent to [Setup]
  4. The [PostCondition] attribute is equivalent to [Test]

In this simple example, I don't have an equivalent to [Teardown] or [TestFixtureTearDown]. I'm sure I'll need those at some point, but until I see the need, I'm not going to worry about them. I also don't really care about the Assert syntax. I'm just putting that syntax in place to illustrate the point.

Where I differ from typical NUnit style of testing is that I want to see a single "PreCondition" and "Execution" per test fixture, and have multiple "PostConditions" that only contain the assert statements. This style of test code more closely resembles that of Scott Bellware's SpecUnit.NET and for good reason - I like it. I'm a fan of having as little as possible in the method that does the assert - keep it simple and explicit.

The biggest problem I have with my proposed syntax is a problem inherent to Design By Contract - the idea that you know the object (contract) being executed. A huge part of why I love Behavior/Specification Testing vs. Unit Testing is that Unit Tests and TestFixtures typically tell you that for class/file "XYZ.cs" you have "TestFixtureXYZ.cs". Whereas, Behavior/Specification Testing says that we have "BehaviorSpecification.cs" regardless of the classes used to implement it. I love this about Behavior Driven Development - it freed my mind from the horrible constraints that I saw in standard Unit Testing / TestFixtures. Unfortunately, Design By Contract basically takes us right back to the same place. We are specifying contract (class) "XYZ" so we have a "XYZContract.cs" file to hold all of our [Conditional]s.

...

Does anyone else see any value in this style of unit testing? I can certainly see scenarios where this would appeal to some developers more than the standard xUnit frameworks.

Wednesday, April 23, 2008 12:48:39 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Agile | Design By Contract | Test Driven Development | Unit Testing

Navigation
About Me
View Derick Bailey's profile on LinkedIn

Send mail to the author(s) Contact Me
Archive
<August 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Derick Bailey
Sign In
Statistics
Total Posts: 65
This Year: 65
This Month: 4
This Week: 0
Comments: 25
Themes
Pick a theme:
All Content © 2008, Derick Bailey
DasBlog theme 'Business' created by Christoph De Baene (delarou)