Sample code and output automatically executed against nspec version 0.9.66 on 2013-04-23 14:21:23 -0500.
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
Debugger Support
DebuggerShim.cs is a class file included with NSpec, you can use that to debug a test using TestDriven.net or Resharper's test runner (we're working on fully integrated support).
Definitely try specwatchr. Specwatchr will automatically run impacted tests for you when you save a file. If you ever need to debug a test simply use this line of code in your test:
System.Diagnostics.Debugger.Launch();
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\src\Sa...
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\src\Sa...
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\src\Sa...
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\src\Sa...
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\src\Sa...
11 Examples, 5 Failed, 0 Pending
before
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
{
//context methods require an underscore. For more info see DefaultConventions.cs.
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
pending
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");
};
}
//helper methods do not have underscores
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;
[Tag("describe_act")]
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;
[Tag("describe_inheritance")]
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
exception
using System;
using NSpec;
class describe_exception : nspec
{
void given_a_null_string()
{
it["should throw null-ref"] =
expect<NullReferenceException>(() => nullString.Trim());
}
string nullString = null;
}
describe 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