The matching of step candidate to textual steps is central to JBehave's design. The first candidate that matches is used to create an executable step. In some case, though, one can have cases in which multiple candidates can match the same textual step, e.g. when the steps are very similar. Moreover, the list of candidates is derived from the method signatures by invoking the Class.getMethods() method, which may return the methods in a different order depending the the version of the JRE.
Steps writers should never rely on the order in which the methods appear in the steps class.For example, the step:
Then the value returned is empty
would be matched by both of the following:
@Then("the value returned is empty") public void theValueIsEmpty() @Then("the value returned is $value") public void theValueIs(String value)
To address this, JBehave's StepFinder allows for a customisable PrioritisingStrategy.
The default strategy is ByPriorityField which prioritises the steps by the priority field explicitly set in the annotations (the default priority is 0). To prioritise one candidate over another simply set a non-zero positive priority:
@Then(value="the value returned is empty", priority=1) public void theValueIsEmpty() @Then("the value returned is $value") public void theValueIs(String value)
An alternative strategy is the ByLevenshteinDistance which prioritises the steps according to the Levenshtein Distance.
To specify a custom strategy, simply create a StepFinder with the desired strategy, and override the default step collector in the configuration:
StepCollector stepCollector = new MarkUnmatchedStepsAsPending(new StepFinder(new ByLevenshteinDistance())); new MostUsefulConfiguration().useStepCollector(stepCollector);