A BDD inspired, declarative developer focused tests framework realized as an xUnit extension.
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
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?
- 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
While SubSpec is inspired by the BDD methodology, its primary strength is to be used as a tool for writing
unit tests. A classical unit test (a Fact in xUnit) consists of three primitive operations:
- Arrange the System Under Test (Context)
- Act on the System Under Test (Do)
- Verify the action had the desired effects (Assert/Observe)
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
, 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):
- Given a new stack with an element pushed onto it, expect the stack is not empty.
- Given a new stack with an element pushed onto it, expect the stacks Top is the pushed element.