Project Description
A BDD inspired, declarative developer focused tests framework realized as an xUnit extension.

About SubSpec

SubSpec allows developers to write declarative tests operating at all layers of abstraction consisting of highly composable, small primitive concepts. Based on the powerful xUnit testing framework, SubSpec is easy to integrate with existing testing environments.


SubSpec was originally started as a demo project by Phil Haack and Brad Wilson to show how a test framework supporting the BDD inspired Specification Style can be implemented on top of the powerful xUnit .Net testing framework.

The original article anouncing the project can be found here. Since then, SubSpec has been officially part of the xUnit Samples project.

SubSpec itself is hosted on bitbucket at https://bitbucket.org/johannesrudolph/subspec/, where you can find additional documentation, source code and binaries.

Why should I care?

SubSpec...
  • helps you to write readable, structured and maintainable** test made from composable primitves.
  • fosters writing descriptive, ** well documented tests**
  • is realized as an xUnit extension** and integrates seamlessly** into your development environment.
  • is smart** about managing disposable test fixtures
  • supports cutting-edge features such as Theories
  • helps you achieve one Assert Per Test** without compromising code quality by duplication
  • is not only for Acceptance testing, its excels at unit testing** just the same

Quickstart !!

While SubSpec is inspired by the BDD methodology, its primary strength is to be used as a tool for writing declarative unit tests. A classical unit test (a Fact in xUnit) consists of three primitive operations:
  1. Arrange the System Under Test (Context)
  2. Act on the System Under Test (Do)
  3. Verify the action had the desired effects (Assert/Observe)

A SubSpec Specification** is constructed using the same primitives. Instead of writing a test method that executes** a test, using SubSpec we write a method that declares** these primitives.

[Specification]
public void PushSpecification()
{
    var sut = default( Stack<int> );
    "Given a new stack"
        .Context( () =>
            sut = new Stack<int>() );

    "with an element pushed onto it"
        .Do( () => 
            sut.Push( 11 ) );

    "expect the stack is not empty"
        .Assert( () =>
            Assert.False( sut.Count == 0 ) );

    "expect the stacks Top is the pushed element"
        .Assert( () =>
        {
            var top = sut.Peek();
            Assert.Equals( 11, top );
        } );   
}

(see Recommended Syntax)

In order to support a fluent syntax, SubSpec allows you to specify each of the primitives as extension methods on strings that describe the primitive action that you pass as an argument to the Context (Arrange), Do (Act), or Assert (well, Assert) method.

Because SubSpec allows you to declare** the tests primitives instead of asking you to execute** them, SubSpecs execution engine is free to compose** them into test cases and take care of executing them. More specifically, SubSpec helps you enforce the "one assert per test" rule by generating two** tests from the previous Specification, one per verification** (see [Documentation#Verifications for more details):
  1. Given a new stack with an element pushed onto it, expect the stack is not empty.
  2. Given a new stack with an element pushed onto it, expect the stacks Top is the pushed element.

Last edited Apr 12, 2011 at 10:28 AM by JohannesRudolph, version 8