Clone wiki

SubSpec / Home

What is 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...

  • 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

Get SubSpec

SubSpec is available as a NuGet package. Visit SubSpec at the NuGet Gallery for instructions and make sure to leave an upvote or review if you like it!


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.

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 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.

Data Driven Testing

For data driven testing we use a SubSpec Thesis attribute, which is an extension of xUnit's Theory attribute. A simple example:

InlineData("goodnight moon", "moon", true),
InlineData("hello world", "hi", false)]
public void Contains(string input, string sub, bool expected)
    var actual = default (bool);

    ("Given a sample input string " + input)
        .Context(() =>
    ("when checked if contains " + sub)
        .Do(() =>
            actual = input.Contains(sub);

    ("it should return " + expected)
        .Assert(() =>
            Assert.Equal(expected, actual);

Note: the test could be written without concatenations of the thesis' parameters.

(see also Thesis attribute example with ClassData)

About SubSpec

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.