Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending a Cucumber step

I have a Cucumber step that looks like this:

When I enter the credentials for the user

and another that says

When I enter the correct credentials for the user

Corresponding step definitions are:

@When("I enter the ([^\"]*) for the user$")
public void stepDefinition(String cred){
    //code
}
@When("I enter the correct ([^\"]*) for the user$")
public void otherStepDefinition(String cred){
    //other code
}

But my second cucumber step ("I enter the correct credentials for the user") is matched by the first step definition, only with the word "correct" added to the credentials.

  1. How do I fix this?
  2. I'm new to regex. Would it be possible to exclude the "correct" part from the 'When' step so I could have a basic step that could be 'extended' with the "correct" part?
like image 248
Mate Mrše Avatar asked Apr 08 '26 02:04

Mate Mrše


2 Answers

The first rule should be changed to

@When("I enter the (\\S+) for the user$")

Here, \S+ matches 1 or more non-whitespace characters. If there can be no non-whitespace chars use \S*.

To match two "words" you may use

@When("I enter the (\\S+\\s+\\S+) for the user$")

Note that you may control the number of "words" using quantifiers, e.g. this will match 2 or 3 words:

@When("I enter the (\\S+(?:\\s+\\S+){1,2}) for the user$")

To match 2 or more words:

@When("I enter the (\\S+(?:\\s+\\S+){1,}) for the user$")
@When("I enter the (\\S+(?:\\s+\\S+)+) for the user$")
like image 53
Wiktor Stribiżew Avatar answered Apr 09 '26 14:04

Wiktor Stribiżew


There are a couple of ways you could improve these steps and avoid the use of regex.

1) Have the user know its credentials and have the step ask the user for the credentials

So you would have


Given I am a user
  @user = create_user # method creates a user with credentials
end

When `I enter the users credentials` do
  fill_in username: @user.username
  fill_in password: @user.password
end

When `I enter the wrong credentials for the user` do
  fill_in username: @user.username
  fill_in password: @user.bad_password # or perhaps just bad_password
end

this approach removes all the complexity from cucumber and places it in the helper methods you are calling to create a user.

2) Have more arguments for your step definition

When 'I enter the credentials user: (\\S+) password: (\\S+) do |username, password|
  fill_in username: username
  fill_in password: password 
end

When 'I enter the bad credentials user: (\\S+) password: (\\S+) do |username, password|
  fill_in username: username
  fill_in password: password 
end

I strongly prefer the first approach, you should keep features and scenarios super simple and push complexity down to code. Code is much better at dealing with complexity than Cucumber.

I've been cuking since before Cucumber was named, and now never use regex's or scenario outlines when I cuke. You don't need to either.

like image 26
diabolist Avatar answered Apr 09 '26 14:04

diabolist