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.
The thing you need to understand is that Specflow is a unit test generation framework. You write your feature files with your gherkin syntax and then create the binding methods attributed with the [Given], [When] and [Then]
and then specflow uses these to generate the unit tests in whichever flavour of unit testing framework you want to use (NUnit, MSTest, XUnit etc etc)
Once you start using specflow you should not mix it with 'raw' NUnit attributes, this will just lead to confusion and difficult to debug issues. Make the change to Specflow and let it manage the generation of the tests
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With