In this post we will see the basics of BDD with xUnit and xBehave. But not only! If you don’t know what are: BDD, Gherkin, integration tests, Cucumber, SpecFlow, xUnit or xBehave, read the following sections. Otherwise, just skip straight to a simple example of an integration test with C# based on xBehave and xUnit.
What is BDD?
BDD means Behavior-Driven Development. It is an Agile software development process that encourages collaboration among developers, QA and non-technical or business participants in a software project. That’s the theory but of course it is not always possible to involve everyone every time. But basically it helps teams to use conversation and concrete examples to formalize a shared understanding of how the application should behave. This allows avoiding issues with misinterpretations. It emerged from Test-Driven Development (TDD). Behavior-driven development combines the general techniques and principles of TDD with ideas from Domain-Driven Design and Object-Oriented analysis and design to provide software development and management teams with shared tools and a shared process to collaborate on software development. Most of the times a common language is used so everyone understand each other: Gherkin.
What is Gherkin?
Gherkin is a business readable, Domain Specific Language created especially for behavior descriptions. It gives you the ability to remove logic details from behavior tests. Gherkin serves two purposes: serving as your project’s documentation and automated tests. It is usually in the form of GIVEN – WHEN – THEN.
What is Cucumber?
Cucumber is a software tool that supports Behavior-Driven Development. Central to the Cucumber BDD approach is its ordinary language parser for Gherkin. It allows expected software behaviors to be specified in a logical language that customers can understand. As such, Cucumber allows the execution of feature documentation written in business-facing text. It runs automated acceptance tests written in a BDD style.
What is SpecFlow?
SpecFlow is a .NET open source framework for Behavior Driven Development, Acceptance Test Driven Development and Specification by Example. The specifications are written in the Gherkin format and it is basically a Cucumber implementation for C#.
What is xUnit?
xUnit.net is a free, open source, community-focused unit testing tool for the .NET Framework. Written by the original inventor of NUnit v2, xUnit.net is the latest technology for unit testing C# and other .NET languages. xUnit.net works with ReSharper, CodeRush, TestDriven.NET and Xamarin.
What is xBehave?
xBehave.net is an xUnit.net extension used to describe tests using natural language. It is one of the best solutions for different testing styles (BDD, TDD, ATDD, etc.). xBehave.net can be used for acceptance tests, integration tests, unit tests or other type of scenarios.
How to use xBehave?
Here we will do a simple example where the structure of the solution will look like this:
So first things first, create your solution and the structure as see above. Now import the NuGet packages for xUnit and xBehave. Then you can start coding your integration test:
using BusinessLogic;
using IntegrationTest_Demo.Base;
using Xbehave;
using Xunit;
namespace IntegrationTest_Demo.Specifications.SalaryCalculation.Given_Employee_Exists
{
public class When_SalaryCalculation_IsTriggered : SpecificationBase
{
[Scenario]
public void Salary_IsCalculated(Employee employee)
{
"Given employee exists"
.x(() =>
{
employee = Helper.Given_Employee_Exists();
});
"When salary is calculated"
.x(() =>
{
employee.Salary = Container.EmployeeBL.CalculateSalaryPerMonth();
});
"Then should have calculated the salary"
.x(() =>
{
Assert.Equal(3752, employee.Salary);
});
}
}
}
Code language: C# (cs)
Where the SpecificationBase the is define as follow:
using IntegrationTest_Demo.SpecificationHelpers;
namespace IntegrationTest_Demo.Base
{
public class SpecificationBase
{
public MyAppContainer Container { get; set; }
public MyAppHelper Helper { get; set; }
public SpecificationBase()
{
Container = new MyAppContainer();
Helper=new MyAppHelper(Container);
}
}
}
Code language: C# (cs)
You can define your own container as follow:
using BusinessLogic;
namespace IntegrationTest_Demo.SpecificationHelpers
{
public class MyAppContainer
{
public MyAppContainer()
{
InitializeDependencies();
}
public IEmployeeBL EmployeeBL { get; set; }
//TODO: construct here manually all your dependencies and injections
//This is a bit long to do sometimes, but helps you to easily visualize dependencies issues (like loops, ...)
public void InitializeDependencies()
{
EmployeeBL = new EmployeeBL();
}
}
}
Code language: C# (cs)
And finally, the Helper class, that can container all the Givens and other useful methods to make your integration tests more readable:
using BusinessLogic;
namespace IntegrationTest_Demo.SpecificationHelpers
{
public class MyAppHelper
{
public MyAppContainer Container { get; set; }
public MyAppHelper(MyAppContainer container)
{
Container = container;
}
public Employee Given_Employee_Exists()
{
var result = Container.EmployeeBL.GetEmployee();
return result;
}
}
}
Code language: C# (cs)
Happy coding! 🙂