Login | Register
My pages Projects Community openCollabNet

nspec
Project home

If you were registered and logged in, you could join this project.

Message from the owner(s)

Current release is v2007.0
Summary A Behaviour Specification Framework for .Net
Categories design, requirements, testing
License zlib/libpng license
Owner(s) timhaughton

NSpec

A Behaviour Specification Framework for .Net.

Behaviour Driven Development

Behaviour Driven Development, or BDD, represents the evolution of current coding practices with respect to Test Driven Development (TDD). Before we introduce BDD and NSpec, let's take a look at some of the currently perceived problems with TDD.

  • Test Driven Development isn't brilliantly named, it hides the fact that TDD is a specification process, not a testing process. Unit tests are about testing, automated tests are about testing, TDD is about specifying.

  • In addition to it's name, the evolutionary roots of TDD have left it with a test oriented nomenclature; we test this, test that, we have test classes, test methods, test fixtures etc. Dan North, Dave Astels et. al. have noted that one of the consequences of this unfortunate terminology is the view that these tests are somehow optional extras that we can use only in a perfect world. Some of the thoughts Dave has harvested on this topic include: �I�m not going to write all those tests.�, �It�s really simple code, it doesn�t need to be tested�, �testing is a waste of time�, or �I�ve done this (loop/data retrieval/functionalty, etc) millions of times.�. And from the project management camp : �we test after the code is done�, �that�s what we have a testing person for�, or �we can�t spend that time now�. In essence, what Dave is saying is that the test oriented nomenclature gives us too many reasons not to write tests, especially when the pressure is on.

  • When we discuss unit testing, what exactly is a unit? It's a tricky term to pin down. And, as Dave has pointed out, it implies that tests are somehow structurally coupled to the production code they 'test'. The end result is often a 1-1 relationship between production and test classes, production and test methods etc. This really isn't what we want, since changing the structure of the production code means changing the structure of the tests.

So, this BDD thing, what's it all about? Well, it takes what developers and coaches have seen and experienced whilst practicing their art, and applies that learning to create something that looks and feels quite different:

  • Whilst I don't think the name BDD is brilliant, it has at least served as a talking point within the community, and as a flag around which the folks pushing BDD can rally.
  • BDD and NSpec have shed the test oriented terminology in favour of a specification friendly nomenclature. As an exercise in Neuro Linguistic Programming, it is hoped that this change in language will help frame more specification oriented thoughts.
  • The structure of the specifications in BDD is not coupled to the structure of the production code. Instead, we organise our specification suites into behavioural chunks, or facets. This structure is then unaffected by changes to the structure of the production code.

The Software

Now the less interesting bit: NSpec. This is the software that will assis .Net developers in using BDD on their projects. Let's jump straight in and look at how to write a specification in NSpec...

 

Firstly, add a reference in your project to NSpec.Framework, then...

using System;

using NSpec.Framework;

  

namespace Example

{

���     [Context]

���     public class Example

���     {

�������         [Specification]

�������         public void BooleanSpecificationExample()

�������         {

�����������             // ...Some set up code...

  

�����������             Specify.That( someObj.SomeMethod() ).ShouldBeFalse();

  

�����������             // Or...

  

�����������             Specify.That( someObj.SomeOtherMethod() ).ShouldBeTrue();

�������         }

  

�������         [Specification]

�������         public void EqualitySpecificationExample()

�������         {

�����������             // ...With objects...

  

�����������             Specify.That( someObj.Foo() ).ShouldEqual( someOtherObj );

  

�����������             // ...Or a with floating point numbers...

  

�����������             Specify.That( someObj.GetSomeFloat() ).ShouldEqual( 5.3 ).WithAToleranceOf( 0.1 );

�������         }

  

�������         [Specification]

�������         public void NullSpecificationExample()

�������         {

�����������             // ...Specify null...

  

�����������             Specify.That( someObj.SomeMethod() ).ShouldBeNull();

  

�����������             // ...Or specify not null...

  

�����������             Specify.That( someObj.SomeFoo() ).ShouldNotBeNull();

�������         }

  

�������         [Specification]

�������         public void ReferentialEqualityExample()

�������         {

�����������             Specify.That( obj.Foo() ).ShouldBeTheSameAs( otherObj.Foo() );

  

�����������             // ...Or specify inequality...

  

��������          ���   Specify.That( obj.Foo() ).ShouldNotBeTheSameAs( otherObj.Foo() );

�������         }

  

�������         [Specification]

�������         public void TypeEqualityExample()

�������         {

�����������             Specify.That( someObj.Bar() ).ShouldBeOfType( typeof( Foo ) );

�������         }

  

�������         [Specification]

�������         public void ExceptionSpecificationExample()

�������         {

�����������             MethodThatThrows mtt = delegate()

�����������             {

���������������                 // Do some set up...

���������������                 // Then call the method that should throw the exception.

�����       ����������          someObj.MethodThrows();

�����������             };

  

�����������             Specify.ThrownBy( mtt ).ShouldBeOfType( typeof(SomeException) );

�������         }

���     }

}

 

Using this syntax, we can build up a specification suite to be run by the console spec runner. To run the specs, use the following syntax...

 

NSpec.Console.exe /assembly:YourAssembly.dll /output:YourPreferredXmlOutFile.xml

 

To produce...

NSpec Console