NSpec is a BDD framework for .NET of the xSpec (context/specification) flavor. NSpec is intended to be used to drive development through specifying behavior at the unit level. NSpec is heavily inspired by RSpec and built upon the NUnit assertion library.
Sample code and output automatically executed against nspec version 0.9.61 on 04/24/2012 at 10:37PM CST
Getting Started
Write Your First Spec
This tutorial will walk you through installing NSpec and running a simple spec.
- Open Visual Studio 2010.
- Ensure that you have NuGet installed. (NuGet only works with VS2010. To use NSpec with VS2008, you must download the binaries zip.)
- Create a .Net 4.0 or .Net 3.5 class library project.
- Open the Package Manager Console and type the following command:
PM> Install-Package nspec
- After installation completes, create a class with the following code:
using NSpec;
class my_first_spec : nspec
{
void given_the_world_has_not_come_to_an_end()
{
it["Hello World should be Hello World"] = () => "Hello World".should_be("Hello World");
}
}
Run Your First Spec
Nuget placed NSpecRunner.exe in your PATH on the Package Manager Console.
- Build the class library.
- Run the following command in the Package Manager Console:
NSpecRunner.exe YourClassLibraryName\bin\debug\YourClassLibraryName.dll
my first spec
given the world has not come to an end
Hello World should be Hello World
1 Examples, 0 Failed, 0 Pending
Specifications
using NSpec;
class describe_specifications : nspec
{
void when_creating_specifications()
{
//some of these specifications are meant to fail so you can see what the output looks like
it["true should be false"] = () => true.should_be_false();
it["enumerable should be empty"] = () => new int[] { }.should_be_empty();
it["enumerable should contain 1"] = () => new[] { 1 }.should_contain(1);
it["enumerable should not contain 1"] = () => new[] { 1 }.should_not_contain(1);
it["1 should be 2"] = () => 1.should_be(2);
it["1 should be 1"] = () => 1.should_be(1);
it["1 should not be 1"] = () => 1.should_not_be(1);
it["1 should not be 2"] = () => 1.should_not_be(2);
it["\"\" should not be null"] = () => "".should_not_be_null();
it["some object should not be null"] = () => someObject.should_not_be_null();
//EXPERIMENTAL - specify only takes a lambda and does
//its best to make a sentence out of the code. YMMV.
specify = ()=> "ninja".should_not_be("pirate");
}
object someObject = null;
}
describe specifications
when creating specifications
true should be false - FAILED - Expected: False, But was: True
enumerable should be empty
enumerable should contain 1
enumerable should not contain 1 - FAILED - Expected: not collection containing 1, But was:...
1 should be 2 - FAILED - Expected: 2, But was: 1
1 should be 1
1 should not be 1 - FAILED - Expected: not 1, But was: 1
1 should not be 2
"" should not be null
some object should not be null - FAILED - Expected: not null, But was: null
ninja should not be pirate
**** FAILURES ****
nspec. describe specifications. when creating specifications. true should be false.
Expected: False, But was: True
at describe_specifications.<when_creating_specifications>b__0() in c:\Projects\NSpec\Sample...
nspec. describe specifications. when creating specifications. enumerable should not contain 1.
Expected: not collection containing 1, But was: < 1 >
at describe_specifications.<when_creating_specifications>b__3() in c:\Projects\NSpec\Sample...
nspec. describe specifications. when creating specifications. 1 should be 2.
Expected: 2, But was: 1
at describe_specifications.<when_creating_specifications>b__4() in c:\Projects\NSpec\Sample...
nspec. describe specifications. when creating specifications. 1 should not be 1.
Expected: not 1, But was: 1
at describe_specifications.<when_creating_specifications>b__6() in c:\Projects\NSpec\Sample...
nspec. describe specifications. when creating specifications. some object should not be null.
Expected: not null, But was: null
at describe_specifications.<when_creating_specifications>b__9() in c:\Projects\NSpec\Sample...
11 Examples, 5 Failed, 0 Pending
Befores
using NSpec;
class describe_before : nspec
{
void they_run_before_each_example()
{
before = () => number = 1;
it["number should be 2"] = () => (number = number + 1).should_be(2);
//even though it was incremented in the previous example
//the before runs again for each spec resetting it to 1
it["number should be 1"] = () => number.should_be(1);
}
int number;
}
describe before
they run before each example
number should be 2
number should be 1
2 Examples, 0 Failed, 0 Pending
Contexts
using NSpec;
class describe_contexts : nspec
{
void describe_Account()
{
//contexts can be nested n-deep and contain befores and specifications
context["when withdrawing cash"] = () =>
{
before = () => account = new Account();
context["account is in credit"] = () =>
{
before = () => account.Balance = 500;
it["the Account dispenses cash"] = () => account.CanWithdraw(60).should_be_true();
};
context["account is overdrawn"] = () =>
{
before = () => account.Balance = -500;
it["the Account does not dispense cash"] = () => account.CanWithdraw(60).should_be_false();
};
};
}
private Account account;
}
describe contexts
describe Account
when withdrawing cash
account is in credit
the Account dispenses cash
account is overdrawn
the Account does not dispense cash
2 Examples, 0 Failed, 0 Pending
Pendings
using NSpec;
class describe_pending : nspec
{
void when_creating_pending_specifications()
{
it["pending spec"] = todo;
//or just add an 'x' at the beginning of a specification that isn't quite ready
xit["\"\" should be \"something else\""] = () => "".should_be("something else");
}
}
describe pending
when creating pending specifications
pending spec - PENDING
"" should be "something else" - PENDING
2 Examples, 0 Failed, 2 Pending
Helpers
using NSpec;
class describe_helpers : nspec
{
void when_making_tea()
{
context["that is 210 degrees"] = () =>
{
before = () => MakeTea(210);
it["should be hot"] = () => tea.Taste().should_be("hot");
};
context["that is 90 degrees"] = () =>
{
before = () => MakeTea(90);
it["should be cold"] = () => tea.Taste().should_be("cold");
};
}
void MakeTea(int temperature)
{
tea = new Tea(temperature);
}
Tea tea;
}
describe helpers
when making tea
that is 210 degrees
should be hot
that is 90 degrees
should be cold
2 Examples, 0 Failed, 0 Pending
Act
using NSpec;
class describe_batman_sound_effects_as_text : nspec
{
void they_are_loud_and_emphatic()
{
//act runs after all the befores, and before each spec
//declares a common act (arrange, act, assert) for all subcontexts
act = () => sound = sound.ToUpper() + "!!!";
context["given bam"] = () =>
{
before = () => sound = "bam";
it["should be BAM!!!"] =
() => sound.should_be("BAM!!!");
};
context["given whack"] = () =>
{
before = () => sound = "whack";
it["should be WHACK!!!"] =
() => sound.should_be("WHACK!!!");
};
}
string sound;
}
describe batman sound effects as text
they are loud and emphatic
given bam
should be BAM!!!
given whack
should be WHACK!!!
2 Examples, 0 Failed, 0 Pending
Class Level
using NSpec;
class describe_class_level : nspec
{
//before, act, and it can also be declared at the class level like so
void before_each()
{
sequence = "arrange, ";
}
void act_each()
{
sequence += "act";
}
//prefixing a method with "it_" or "specify_"
//will tell nspec to treat the method as an example
void specify_given_befores_and_acts_run_in_the_correct_sequence()
{
sequence.should_be("arrange, act");
}
string sequence;
}
describe class level specify given befores and acts run in the correct sequence 1 Examples, 0 Failed, 0 Pending
Inheritance
using NSpec;
class given_the_sequence_continues_with_2 : given_the_sequence_starts_with_1
{
void before_each()
{
sequence += "2";
}
void given_the_sequence_continues_with_3()
{
before = () => sequence += "3";
//the befores run in the order you would expect
it["sequence should be \"123\""] =
() => sequence.should_be("123");
}
}
class given_the_sequence_starts_with_1 : nspec
{
void before_each()
{
sequence = "1";
}
protected string sequence;
}
given the sequence starts with 1
given the sequence continues with 2
given the sequence continues with 3
sequence should be "123"
1 Examples, 0 Failed, 0 Pending
Exceptions
using System;
using NSpec;
class describe_expected_exception : nspec
{
void given_a_null_string()
{
it["should throw null-ref"] =
expect<NullReferenceException>(() => nullString.Trim());
}
string nullString = null;
}
describe expected exception
given a null string
should throw null-ref
1 Examples, 0 Failed, 0 Pending
Summary
- Install via NuGet (VS2010 only)
- or download zip from github https://github.com/mattflo/NSpec/downloads
- Requires .NET 3.5
- Classes inherit from nspec
- Classes and methods
- are contexts
- do not require an access modifier
- Inside methods
- sub contexts are created (context/describe)
- specifications are declared (it/specify)
- before lambdas are assigned that run before each specification
- act lambdas are assigned that run after befores but before specifications