-
-
Notifications
You must be signed in to change notification settings - Fork 46
Writing scenarios
xBehave.net scenarios are very similar to Cucumber scenarios.
The basic anatomy of a scenario is:
- A containing assembly
- A containing type (e.g. C# class)
- A scenario (e.g. C# method)
- Some steps (e.g. delegates defined inside a C# method)
A containing assembly contains the tests for the features or specs of your system under test (SUT). E.g. if the library you want to test is named Widgets
, you might create a library named Widgets.Features
or Widget.Specs
(see What kind of tests can I write using xBehave.net?). This is the equivalent of creating a test library using xUnit.net or NUnit.
A containing type groups your scenarios together. E.g. if one of your features is a calculator, you might create a class named CalculatorFeature
. This is the equivalent of creating a test class to contain a set of xUnit.net facts or NUnit tests.
The name of your scenario should describe it adequately. E.g. if you want to cover the scenario of adding numbers together with your calculator then you might name the scenario Addition
.
The steps within a scenario contain the code which is executed during the scenario and typically defined using the vocabulary of Gherkin.
Let's take a look at an example.
namespace Widgets
{
public class Calculator
{
public int Add(int x, int y)
{
return x + y;
}
}
}
namespace Widgets.Features
{
using FluentAssertions;
using Xbehave;
// In order to build complicated widgets
// As a widget builder
// I want a calculator for performing basic arithmetic
public class CalculatorFeature
{
[Scenario]
public void Addition(int x, int y, Calculator calculator, int answer)
{
"Given the number 1"
.Given(() => x = 1);
"And the number 2"
.And(() => y = 2);
"And a calculator"
.And(() => calculator = new Calculator());
"When I add the numbers together"
.When(() => answer = calculator.Add(x, y));
"Then the answer is 3"
.Then(() => answer.Should().Be(3));
}
}
}
Let's examine this scenario bit by bit.
First of all we have our feature introduction:
// In order to build complicated widgets
// As a widget builder
// I want a calculator for performing basic arithmetic
public class CalculatorFeature
As in Cucumber, this is free text which is not parsed. Its purpose is to describe the feature to the reader. The name of the feature is the class name, which is the equivalent of the first line of a Cucumber feature introduction.
Next we have the scenario name:
[Scenario]
public void Addition(int x, int y, Calculator calculator, int answer)
The [Scenario]
attribute marks the method as a scenario and is the equivalent of the xUnit.net [Fact]
and NUnit [Test]
attributes. The name of the scenario is the method name.
The parameters of the method are simply a shorthand way of declaring the variables which will be used within the scenario steps. The method will be invoked with default values passed for each parameter, i.e. null
for reference types and zero values for value types. You can also supply example values for these parameters for executing scenarios in a data-driven/spec by example manner (see Scenarios with examples).
Lastly are the steps themselves. In this example, they are directly equivalent to Cucumber steps. Like Cucumber, xBehave.net does not distinguish between each type of step. It is up to you to organise them as you see fit. All the Gherkin step types, (Given, When, Then, And, But) are built in, but you don't have to use these if you don't want to. You can use the more general f or _ methods or you can even extend xBehave.net with your own vocabulary (see Extending xBehave.net.