I am new to NUnit and confused with the SpecFlow Testing Framework and NUnit Testing Framework.
The existing project uses NUnit, something like this below. All the methods with [Test] attribute are displayed in the NUnit GUI (if I remove [Test] from the method, the test case is not display in NUnit GUI):
[TestFixture]
public class AccountTest
{
[Test]
public void TransferFunds()
{
Account source = new Account();
source.Deposit(200m);
}
[Test]
public void TransferWithInsufficientFunds()
{
}
}
When I code with SpecFlow in the same project, the SpecFlow framework is different, starting with [Given], [When], [Then]. And each SpecFlow scenario is displayed at the Nunit GUI.
What I am doing is replacing each [Test] method with one SpecFlow method. E.g.:
[Test]
public void TransferFunds()
{
Account source = new Account();
source.Deposit(200m);
}
Turns to
[Then(@"I Transfer Funds")]
public void ITransferFunds()
{
Account source = new Account();
source.Deposit(200m);
}
Here is my question:
It looks like SpecFlow does not recognize the NUnit attributes [Test] or [Setup]. To do the project with SpecFlow, do I need to get rid of all NUnit framework and replace with SpecFlow's framework?
I can see there is many articles talking about "SpecFlow + NUnit", but they are either with SpecFlow [Given], [When], [Then] or NUnit [Test], [TestCase]. How to make both work in one project or is my understanding of NUnit is totally wrong?
My question might be very entry level, thanks for the answers!
Do I need to get rid of all NUnit framework and replace with SpecFlow's framework?
The first thing I think you need to understand is that NUnit
and SpecFlow
are not mutually exclusive.
SpecFlow
as a whole has a lot of components, but what you need to understand now is that SpecFlow
is used to bind feature files written in Gherkin
to C#
code that can be run by a test runner. That C#
code has two parts, the auto-generated one, and the one written by you and your team.
The part written by you are those methods with the attributes Given
, When
, and Then
. They are the step definitions (read more here). These bindings need to follow these rules:
- Must be in a public class, marked with the
[Binding]
attribute.- Must be a public method.
- Can be either a static or an instance method. If it is an instance method, the >* containing class will be instantiated once for every scenario.
- Cannot have out or ref parameters.
- Cannot have a return type.
The auto-generated part generates tests methods written using NUnit
, MSTest
, xUnit
among other available unit test providers. As you can see, with the same Gherkin (here and here) you end up with different auto-generated files (here and here)
Let's take a look at a specific scenario (source)
Scenario: One single spare
Given a new bowling game
When I roll the following series: 3,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Then my total score should be 29
If the Unit Test Provider is NUnit
that step will generate the following test method (source):
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("One single spare")]
public virtual void OneSingleSpare()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("One single spare", ((string[])(null)));
#line 7
this.ScenarioSetup(scenarioInfo);
#line 8
testRunner.Given("a new bowling game");
#line 9
testRunner.When("I roll the following series:\t3,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1");
#line 10
testRunner.Then("my total score should be 29");
#line hidden
testRunner.CollectScenarioErrors();
}
If the Unit Test Provider is xUnit
that step will generate the following test method (source):
[Xunit.FactAttribute()]
[Xunit.TraitAttribute("FeatureTitle", "Score Calculation (alternative forms)")]
[Xunit.TraitAttribute("Description", "One single spare")]
public virtual void OneSingleSpare()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("One single spare", ((string[])(null)));
#line 7
this.ScenarioSetup(scenarioInfo);
#line 8
testRunner.Given("a new bowling game");
#line 9
testRunner.When("I roll the following series:\t3,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1");
#line 10
testRunner.Then("my total score should be 29");
#line hidden
testRunner.CollectScenarioErrors();
}
No matter what Unit Test Provider you're using, your step definitions methods will look almost* the same (as you can see here for NUnit
and here for xUnit
).
There are a few different step definition styles you can use. They are described here
*The only difference might be your assertions.