A Step Definition is a methodfunctionblockfunctionfunction with an expression that links it to one or more Gherkin steps.
When Cucumber executes a Gherkin step in a scenario, it will look for a matching step definition to execute.
To illustrate how this works, look at the following Gherkin Scenario:
Scenario: Some cukes
Given I have 48 cukes in my belly
The I have 48 cukes in my belly
part of the step (the text following the Given
keyword) will match the following step definition:
package com.example;
import io.cucumber.java.en.Given;
public class StepDefinitions {
@Given("I have {int} cukes in my belly")
public void i_have_n_cukes_in_my_belly(int cukes) {
System.out.format("Cukes: %n\n", cukes);
}
}
Or, using Java8 lambdas:
package com.example;
import io.cucumber.java8.En;
public class StepDefinitions implements En {
public StepDefinitions() {
Given("I have {int} cukes in my belly", (Integer cukes) -> {
System.out.format("Cukes: %n\n", cukes);
});
}
}
package com.example
import io.cucumber.java8.En
class StepDefinitions : En {
init {
Given("I have {int} cukes in my belly") { cukes: Int ->
println("Cukes: $cukes")
}
}
}
package com.example
import io.cucumber.scala.{ScalaDsl, EN}
class StepDefinitions extends ScalaDsl with EN {
Given("I have {int} cukes in my belly") { cukes: Int =>
println(s"Cukes: $cukes")
}
}
Given('I have {int} cukes in my belly') do |cukes|
puts "Cukes: #{cukes}"
end
const { Given } = require('cucumber')
Given('I have {int} cukes in my belly', function (cukes) {
console.log(`Cukes: ${cukes}`)
});
Expressions
A step definition’s expression can either be a Regular Expression
or a Cucumber Expression. The examples in this section use Cucumber Expressions.
If you prefer to use Regular Expressions, each capture group
capture group
capture group
output parameter
output parameter
from the match will be passed as arguments to the step
definition’s methodfunctionblockfunctionfunction.
@Given("I have {int} cukes in my belly")
public void i_have_n_cukes_in_my_belly(int cukes) {
}
Given("I have {int} cukes in my belly") { cukes: Int ->
println("Cukes: $cukes")
}
Given("I have {int} cukes in my belly") { cukes: Int =>
println(s"Cukes: $cukes")
}
Given(/I have {int} cukes in my belly/) do |cukes|
end
Given(/I have {int} cukes in my belly/, function (cukes) {
});
If the capture group
capture group
capture group
output parameter
output parameter
expression is identical to one of the registered
parameter types’s regexp
,
the captured string will be transformed before it is passed to the
step definition’s methodfunctionblockfunctionfunction. In the example above, the cukes
argument will be an integer, because the built-in int
parameter type’s
regexp
is \d+
.
State management
A step definition can transfer state to a subsequent step definition by storing
state in instance variables.
Please note that if you use arrow functions, you will have to create a variable representing state outside of the steps, in order to share state between steps!
let cukesState;
Given('I have {int} cukes in my belly', cukes => {
cukesState = cukes
})
Scope
Step definitions aren’t linked to a particular feature file or scenario.
The file, class or package name of a step definition does not affect what Gherkin
steps it will match. The only thing that matters is the step definition’s
expression.
Snippets
When Cucumber encounters a Gherkin step without a
matching step definition, it will print a
step definition snippet with a matching Cucumber Expression.
You can use this as a starting point for new step definitions.
Consider this Gherkin step:
Given I have 3 red balls
If you don’t have a matching step definition, Cucumber will suggest the following
snippet:
@Given("I have {int} red balls")
public void i_have_red_balls(int int1) {
}
@Given("I have {int} red balls") { balls: Int ->
}
Given("I have {int} red balls") { balls: Int =>
}
Given('I have {int} red balls') do |int1|
end
Given("I have {int} red balls", function (int1) {
});
Suggested snippets will use your own parameter types
if they match parts of your undefined step. If a color
parameter type exists, Cucumber would use that in the suggested expression:
@Given("I have {int} {color} balls")
public void i_have_color_balls(int int1, Color color) {
}
@Given("I have {int} {color} balls") { balls: Int, color: Color ->
}
}
Given("I have {int} {color} balls") { (balls: Int, color: Color) =>
}
Given('I have {int} {color} balls') do |int1, color|
end
Given("I have {int} {color} balls", function (int1, color) {
});
Make sure you use the summary
plugin when running Cucumber in order
to have the snippets printed.