Nunit Framework vs SpecFlow Framework

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


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.

Tags:

C#

Nunit

Specflow