Authoring stories with BDD using Behave# and NSpec
This post was originally published here.
A question came up on the Behave# CodePlex site, asking about the intent of Behave# and where it fits with NSpec. BDD is all about using TDD to create specifications, and NSpec bridges the gap with a specification-friendly API. For me, the question of when to write Behave# stories and pure NSpec specifications is fairly straightforward.
The stories and scenarios created by the business owner should be captured in Behave# stories and scenarios. The specifications of everything else should be captured by NSpec (or NUnit.Spec, or NUnit constraints).
But that’s not stopping us from using NSpec for the “Then” fragment of a scenario.
Anatomy of a scenario
A scenario is composed of three distinct sections: Context, Event, and Outcome. The scenario description follows the pattern “Given
Story: Transfer to cash account As a savings account holder I want to transfer money from my savings account So that I can get cash easily from an ATM Scenario: Savings account is in credit Given my savings account balance is $100 And my cash account balance is $10 When I transfer to cash account $20 Then my savings account balance should be $80 And my cash account balance should be $30
My outcomes are the “Then” fragment of the scenario, but could also be interpreted as specifications for an account.
Using NSpec with Behave#
So how can we combine NSpec with Behave#? Here’s the story above written with NSpec and Behave#:
Account savings = null; Account cash = null; Story transferStory = new Story("Transfer to cash account"); transferStory .AsA("savings account holder") .IWant("to transfer money from my savings account") .SoThat("I can get cash easily from an ATM"); transferStory .WithScenario("Savings account is in credit") .Given("my savings account balance is", 100, delegate(int accountBalance) { savings = new Account(accountBalance); }) .And("my cash account balance is", 10, delegate(int accountBalance) { cash = new Account(accountBalance); }) .When("I transfer to cash account", 20, delegate(int transferAmount) { savings.TransferTo(cash, transferAmount); }) .Then("my savings account balance should be", 80, delegate(int expectedBalance) { Specify.That(savings.Balance).ShouldEqual(expectedBalance); }) .And("my cash account balance should be", 30, delegate(int expectedBalance) { Specify.That(cash.Balance).ShouldEqual(expectedBalance); })
Note that in the “Then” fragment of the Scenario, I’m using NSpec to specify the outcomes. By using NSpec and Behave# together to author business owner stories in to executable code, I’m able to combine both the story/scenario side of BDD with the specification side.