Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specflow Scenario Outline not generating expected step code

Here is my gherkin:

Scenario Outline: Login using valid email address
Given I have not logged into the current computer
And Username <username> and password <password> is a valid account
When I start the client
And Login using username <username> and password <password>
Then The client should navigate to first time screen

Examples: 
| username         | password    |
| [email protected] | password001 |
| valid002         | password002 |

This generates the following step file:

[Binding]
public class UserLoginSteps
{
    [Given(@"I have not logged into the current computer")]
    public void GivenIHaveNotLoggedIntoTheCurrentComputer()
    {
        ScenarioContext.Current.Pending();
    }

    [Given(@"Username valid(.*)@xyz\.com and password password(.*) is a valid account")]
    public void GivenUsernameValidXyz_ComAndPasswordPasswordIsAValidAccount(int p0, int p1)
    {
        ScenarioContext.Current.Pending();
    }

    [When(@"I start the client")]
    public void WhenIStartTheClient()
    {
        ScenarioContext.Current.Pending();
    }

    [When(@"Login using username valid(.*)@xyz\.com and password password(.*)")]
    public void WhenLoginUsingUsernameValidXyz_ComAndPasswordPassword(int p0, int p1)
    {
        ScenarioContext.Current.Pending();
    }

    [Then(@"The client should navigate to first time screen")]
    public void ThenTheClientShouldNavigateToFirstTimeScreen()
    {
        ScenarioContext.Current.Pending();
    }
}

The problems are as follows:

  • Generated regex for username is based on the first entry in the examples column. This is not what I want as not all examples follow that pattern.
  • The method names are using the first entry in the examples column (i.e. WhenLoginUsingUsernameValidXyz_ComAndPasswordPassword). This is hard to read and if the data in the examples table changes the method name is no longer correct
  • The type for the parameters are int. They should be string.

I would expect the step definition generation to output something like this:

    [When(@"Login using username (.*) and password (.*)")]
    public void WhenLoginUsingUsernameAndPassword(string p0, string p1)
    {
        ScenarioContext.Current.Pending();
    }

Am I missing something? Is there a way to influence the way SpecFlow generates step methods for Scenario Outlines? If not, what is the best way to fix this without having the feature generated code behind clobbering my changes

like image 726
IUnknown Avatar asked Dec 12 '13 00:12

IUnknown


2 Answers

In short, good news. These auto-generated bindings are just a convenience and do not automatically get regenerated. In fact I've always built these by hand myself.

This means you can go and change them without worrying about them getting clobbered :-)

SpecFlow works by auto-generating *.feature.cs files every time you edit a *.feature file. These should never be edited, but if you look through them you can see that they basically takes the Given, When, and Then lines from your scenarios and passes them as arguments to its own internal methods. Behind the scenes, SpecFlow uses reflection to find all of your classes that have a [Binding] attribute on them, then looks through all of those classes methods which have [Given], [When] or [Then] attributes to find a list of regexes. The best matching regex identifies the method to call. This is why Bindings are often described as global and shouldn't really be built using inheritance (as you end up with multiple identical regexes).

Coming back to the generated bindings that you have, these are only created in the editor when SpecFlow's VS plugin detects that you don't have a matching regex and you try to navigate to a definition (F12) in a feature file. They really are placeholders for you to build from.

like image 164
AlSki Avatar answered Nov 18 '22 01:11

AlSki


You should use single quotes to signify that SpecFlow has to use the whole string instead of the number.

Examples: 
| username           | password      |
| '[email protected]' | 'password001' |
| 'valid002'         | 'password002' |
like image 1
476rick Avatar answered Nov 18 '22 02:11

476rick