Specflow beginner tutorial

By | April 18, 2016

This c# based Specflow beginner tutorial will just focus on fundamentals to get you off to a quick start. At the end of this post you will be having a working Specflow solution. I will be writing other posts on Specflow which will highlight different aspects of Specflow.
As usual I will discuss the WHY first followed by HOW.

WHY
Any product follows more or less same life cycle. First the requirements are fleshed out and then the engineering team implements it. But how do we know that final product actually does what it was required to do? Can we have something which can actually check if all the requirements are met? Unit test cases do not cut here. Their scope is limited to function level. Here we are talking of system level.

Enter Specflow. Specflow allows you to write your requirements in a human readable way(the syntax inside Specflow file is that of Gherkin to be exact). It is almost 90% similar to what a normal person will be writing if he was writing requirements on a word document. With the added bonus that test engineers can write code behind each of the requirement statement. When Specflow is run then it can verify that the product under test meets all the requirements listed in it. Yes, we just automated the Acceptance testing. There is lot more to talk about but since this is a Specflow beginner tutorial I will stop here.

HOW

  1. First let us setup visual studio for Specflow.
  2. First in the Visual Studio install the SpecFlow. Go to Tools->Extensions and Updates. Go  online and install Specflow.
  3. Create a Visual C# “Class Library Project”. Lets call it “Batman”. Remove the default “Class1.cs” file.
  4. Add SpecFlow.xUnit. Use NuGet package manager for this.
  5. Then Right click on the project and use Add->New Item->SpecFlow Feature file. Name it ‘Weapons.feature’. Delete everything in it for time being. We will come to this later.

Before we go into nitty gritty of code, let us take a high level view of things. Specflow gels best with requirements fleshed out in form of Use cases. There is a school of thought that says that requirements should be listed in form of Use cases. Myself and Specflow are both graduates of that school.

Specflow files have extension “.feature”. For a good reason. Say you have a product called Batmobile. It has many features like Autopilot, Self Destruct not to mention the Weapons. Each of the feature will warrant a separate Specflow feature file.

Put this in Weapons.feature file.

Feature: Batmobile Weapons
    In order fight villains
    As Batman
    I want to fire weapons from Batmobile.

Note:

  • The syntax in Specflow file is Gherkin.
  • Feature is a keyword. It is supposed to be followed by colon and then the name of the feature.
  • The text from line 2 to 4 is free hand text. You can write anything. But the ‘convention’ in Gherkin land is:
            In order to….
            As …..
            I want …..

Specflow Feature is made up of scenarios.
So what are scenarios?
Let us discuss the Weapons feature.
The main use case here is:

  1. I see villain.
  2. I press fire cannon button.
  3. Batmobile cannons fire.

Some of the alternatives and edge cases here will be like below. The success of the project critically depends on this list. The stakeholders should typically brainstorm this down to the Nth degree and cover as many alternate and edge cases as humanely possible.

One scenario might be this.

  1. I see villain.
  2. I press fire cannon button.
  3. I am out of ammunition.
  4. Batmobile says “Try rockets”.

Another might be this.

  1. I see villain.
  2. I press fire cannon button.
  3. Weapon system malfunction.
  4. Batmobile says “Batpod time?”.

The list can be quite long. But I will stop at this last one. This is a Specflow beginner tutorial and I have proved my point.

  1. I see villain.
  2. I press fire cannon button.
  3. Villain is still standing.
  4. Batmobile says “Run”.

Each of these Use cases are scenarios. These use cases are all related to the given feature (Batmobile Weapons) and they come together in a specflow feature file.
Let us come back to Weapons.feature and add the main use case. Now the Weapons.feature looks like this.

Feature: Batmobile Weapons
    In order fight villains
    As Batman
    I want to fire weapons from Batmobile.

Scenario: Fire Cannon successfully
    Given I see villain
    When I press fire cannon button
    Then Batmobile cannons fire

Note:

  • Scenario is a Gherkin keyword and is followed by colon and the name of the scenario (read use case).
  • Given, When and Then are also Gherkin keywords. They are to be used to write the use cases. Turns out that using them you can write almost any use case.
  • There are addition keywords And and But to make the scenario more readable. As you can see below.

    Scenario:
    Villain survives attack
            Given I see villain
            When I press fire cannon button
            When Villain is still standing
            Then Batmobile engages escape mode
            Then I say not yet

    Scenario:
    Villain survives attack
            Given I see villain
            When I press fire cannon button
            And Villain is still standing
            Then Batmobile engages escape mode
            But I say not yet 
    Internally all the And and But keywords map to the Given, When or Then under which they appear.

We will add one more scenario to Weapons.feature. Just two scenarios will be enough. This is a Specflow beginner tutorial after all.

Feature: Batmobile Weapons
    In order fight villains
    As Batman
    I want to fire weapons from Batmobile.

Scenario: Fire Cannon successfully
    Given I see villain
    When I press fire cannon button
    Then Batmobile cannons fire

Scenario: Villain survives attack
    Given I see villain
    When I press fire cannon button
    And Villain is still standing
    Then Batmobile engages escape mode
    But I say not yet

Now it is time to generate the code behind. Just right click on each of the statement and click on generate step definitions. Choose Style as ‘Regular expressions in attributes’. It looks ugly but gives maximum power. Maybe I will write a post on that later. It will ask where to store the generated c# file. Choose the same folder where the feature file is there to make things simpler. This is a Specflow beginner tutorial and I will keep things deliberately simple. We will save the file as BatmobileWeaponsSteps.cs and here it is in its full glory.

using TechTalk.SpecFlow;
using Xunit;

namespace Batman
{
    [Binding]
    public class BatmobileWeaponsSteps
    {
        [Given(@"I see villain")]
        public void GivenISeeVillain()
        {
            ScenarioContext.Current.Pending();
        }

        [When(@"I press fire cannon button")]
        public void WhenIPressFireCannonButton()
        {
            ScenarioContext.Current.Pending();
        }

        [When(@"Villain is still standing")]
        public void WhenVillainIsStillStanding()
        {
            ScenarioContext.Current.Pending();
        }

        [Then(@"Batmobile cannons fire")]
        public void ThenBatmobileCannonsFire()
        {
            ScenarioContext.Current.Pending();
        }

        [Then(@"Batmobile engages escape mode")]
        public void ThenBatmobileEngagesEscapeMode()
        {
            ScenarioContext.Current.Pending();
        }

        [Then(@"I say not yet")]
        public void ThenISayNotYet()
        {
            ScenarioContext.Current.Pending();
        }
    }
}

Read the function names. Rings a bell? Yes. They are same as the specflow statements we wrote.

  • Each of the function is decorated with Given, Then and When attribute. Notice that And and But do not appear. They get replaced by the immediate Given, When or Then preceding them.
  • The body of the functions has `ScenarioContext.Current.Pending()` in it. It means that the implementation is still pending

I will cheat my way out of this. I will just write some asserts in this which will just pass.
See the file below:

using TechTalk.SpecFlow;
using Xunit;

namespace Batman
{
    [Binding]
    public class BatmobileWeaponsSteps
    {
        [Given(@"I see villain")]
        public void GivenISeeVillain()
        {
            Assert.Equal(1, 1);
        }

        [When(@"I press fire cannon button")]
        public void WhenIPressFireCannonButton()
        {
            Assert.Equal(1, 1);
        }

        [When(@"Villain is still standing")]
        public void WhenVillainIsStillStanding()
        {
            Assert.Equal(1, 1);
        }

        [Then(@"Batmobile cannons fire")]
        public void ThenBatmobileCannonsFire()
        {
            Assert.Equal(1, 1);
        }

        [Then(@"Batmobile engages escape mode")]
        public void ThenBatmobileEngagesEscapeMode()
        {
            Assert.Equal(1, 1);
        }

        [Then(@"I say not yet")]
        public void ThenISayNotYet()
        {
            Assert.Equal(1, 1);
        }
    }
}

Now this is a bit too simple. But then I want to keep this a Specflow beginner tutorial. And as promised, it runs. The tests naturally pass.
Specflow beginner tutorial
In the next post I will start adding more complexity to this Specflow beginner tutorial and make it more like a real world example.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.