Behat Duplicate and Ambiguous Step Definitions

Profile picture for user devraj

Over the time, your project size will increase, we already have several step definitions in Mink and Drupal and we also create our own in FeatureContext. We might have even our custom files like FeatureContext. With increase in number of step definitions, sometime while writing Step Definition in Behat we create duplicate and ambiguous step definitions. So, When we have multiple Steps Definitions file or Large Project these errors are obvious. 

If Behat encounters duplicate or ambiguous Steps, all the other Steps of the Scenarios are skipped and Scenario is marked as fail.

You do not have to be much worried for this because Behat itself identify it and return error for you and it will also tell you the method name which is creating these problems.

Duplicate Step Definition in Behat

Suppose you declared same step definition in multiple classes, in that case you will get step definition already defined error along with class name. Below step definition I have used in FeatureContext and CustomFun class with exactly same method name and pattern. As already discussed this still duplicate even you change this Then with Given or When.

/**
  * @Then this is my step definition
  */
public function thisIsMyStepDefinition()
{
}
Step "this is my step definition" is already defined in FeatureContext::thisIsMyStepDefinition()
      
FeatureContext::thisIsMyStepDefinition()
CustomFun::thisIsMyStepDefinition()

You will also get the similar error if you have used exactly same pattern but different method name in same class:

/**
 * @Given this is my step definition
 */
public function thisIsMyStepDefinition()
{
}

/**
 * @Given this is my step definition
 */
public function xyz()
{
}
Step "this is my step definition" is already defined in FeatureContext::thisIsMyStepDefinition()
      
FeatureContext::thisIsMyStepDefinition()
FeatureContext::xyz()

Ambiguous Step Definition in Behat

When Behat Found multiple Step Definitions that are a partial match, it throws an ambiguous Step Definitions exception. This happens when you play around with regular expression.

A simple example is, Given I am on the homepage step is already defined in MinkContext.

/**
 * Opens homepage
 * Example: Given I am on "/"
 * Example: When I go to "/"
 * Example: And I go to "/"
 *
 * @Given /^(?:|I )am on (?:|the )homepage$/
 * @When /^(?:|I )go to (?:|the )homepage$/
 */
    public function iAmOnHomepage()
    {
        $this->visitPath('/');
        echo "Background is executed";
    }

So, several steps like below will call the above step definition.

Given I am on the homepage
Given I am on homepage
When I go to the homepage
When I go to homepage

Now, consider one of your team member don't know much about regular expression and; another case could be you don't have feature rich editor like PHPStorm which help you to autocomplete or directly navigate to steps, in that case you have declared similar step definition of your own like:

/**
  * @Given I am on the homepage
  */
public function i_am_on_the_homepage()
{
}

 In that case, you will get ambiguous match error

Ambiguous match of "I am on the homepage":
to `I am on the homepage` from FeatureContext::i_am_on_the_homepage()
to `/^(?:|I )am on (?:|the )homepage$/` from Drupal\DrupalExtension\Context\MinkContext::iAmOnHomepage()

So, these are 2 types of error, you might encounter while working on large scale project or as you add more step definition to your project.

Tags