Subash
Subash

Reputation: 7256

Regex match in cucumber but not capture it

I am using specflow to write my browser tests using Gherkin syntax. I have a step definition where I want to match 2 different steps but not capture it. For eg:

Scenario:
  Given I have some stuff
  And I click on the configure user 
  And I configure user
  And I set the user <config> to <value>
  Then I should see user configuration is updated

Scenario:
  Given I have some stuff
  And I click on the configure admin
  And I configure admin
  And I set the admin <config> to <value>
  Then I should see user configuration is updated

The step definition regex for And I set the admin <config> to <value> would be something like:

Given(@"And I set the admin (.*) to (.*)")
public void AndISetTheAdminConfigToValue(string config, string value) 
{
    // implementation
}

And for And I set the user <config> to <value> would be like:

Given(@"And I set the admin (.*) to (.*)")
public void AndISetTheUserConfigToValue(string config, string value) 
{
    // implementation
}

The implementation of both steps are same. So what I would like to do is:

Given(@"And I set the user|admin (.*) to (.*)")
public void AndISetTheConfigToValue(string config, string value) 
{
    // implementation
}

The above code will not work as config and value parameters will be empty string as user and admin are captured as first 2 parameters.

Is there a way to do something like above without capturing the regex matches in the parameter?

I know that I can simply rewrite the scenario to be as follows to resolve the issue. But I am just curious.

Scenario:
  Given I have some stuff
  And I click on the configure admin
  And I configure admin
  And I set the <config> to <value>
  Then I should see user configuration is updated

Upvotes: 0

Views: 2406

Answers (2)

kfairns
kfairns

Reputation: 3057

Using what AlSki has provided as a baseline:

Using an optional group would also be an option here:

[Given(@"I set the (?:user|admin) (.*) to (.*)"]
public void ISetTheConfigValue(string config, string value)

Which will mean that you dont have to include a parameter you will never use.

I would recommend getting rid of the pesky (.*) regex, which will match anything and everything that you put in there - a problem later on if you want a step that will grab the privileges that that user can have (as an example):

Given I set the user JohnSmith to an admin with example privileges

So I would personally use this:

[Given(@'I set the (?:user|admin) "([^"]*)" to "([^"]*)"']
public void ISetTheConfigValue(string config, string value)

Which would match:

Given I set the user "JohnSmith" to "SysAdmin"
And I set the admin "JaneDoe" to "User"

But would not match

Given I set the user JohnSmith to an admin with example privileges

Upvotes: 4

AlSki
AlSki

Reputation: 6961

Firstly be careful of having multiple (.*)s in the same binding as it can lead to catching the wrong patterns.

Without checking I'm pretty sure that it is possible to provide multiple bindings on the method, as long as they have the same parameter count, i.e.

 [Given("I set the user (.*) to (.*)"]
 [Given("I set the admin (.*) to (.*)"]
 public void ISetTheConfigValue(string config, string value)  

Alternatively, you can always add a dummy parameter,

 [Given("I set the (user|admin) (.*) to (.*)"]
 public void ISetTheConfigValue(string _, string config, string value)

Upvotes: 2

Related Questions