Skip to main content

Cucumber Annotations

Two related capabilities: generating @Given / @When / @Then Cucumber annotations on step methods, and using those annotations to match steps to implementations by pattern instead of by method name.

This is especially useful when migrating from an existing Cucumber setup: your current @Given / @When / @Then step definitions can be matched by their annotation patterns, letting you reuse them under SpecBinder without renaming methods to fit its naming convention.

Source: examples/going-further/example-6 on GitHub.

What this demonstrates

1. Generating Cucumber annotations

  • @Gherkin2JUnitOptions(addCucumberStepAnnotations = true) adds annotations from io.cucumber.java.en.*
  • Each step method receives a @Given / @When / @Then with a pattern matching the original Gherkin step text
  • And / But steps inherit the keyword from the preceding Given / When / Then
  • Requires the cucumber-java dependency

2. Annotation-based step matching

  • useCucumberAnnotationsForStepMatching defaults to false; enable it with @Gherkin2JUnitOptions(useCucumberAnnotationsForStepMatching = true) (as this example does)
  • When the generator looks for already-implemented steps in the marker hierarchy, it matches by annotation pattern, not method name
  • You can use any method name you like — as long as the annotation pattern matches the Gherkin step text, the generator recognises the method as an implementation and won't emit a stub or abstract declaration

3. Two pattern styles work

The annotation value can be either:

  • A Cucumber expression — e.g. @When("I apply discount code {string}")
  • A regular expression — e.g. @When("^I add \"([^\"]*)\" to the cart$")

Both are equally valid for matching, and you can mix the two within a single class.

Custom method names with annotation matching

Gherkin stepCustom method namePattern styleAnnotation
Given I have an empty shopping cartstartWithEmptyCart()Cucumber expression@Given("I have an empty shopping cart")
When I add "..." to the cartaddItemToCart()Regular expression@When("^I add (?<p1>.*) to the cart$")
Then the cart should contain "..." itemsverifyCartSize()Regular expression@Then("^the cart should contain (?<p1>.*) items$")
When I apply discount code "..."applyDiscount()Cucumber expression@When("I apply discount code {string}")
Then the cart subtotal should be "..."verifySubtotal()Cucumber expression@Then("the cart subtotal should be {string}")

Because every step has a matching implementation on the marker class, the generated test class contains no step declarations at all — only the @Test scenarios that delegate to the inherited methods.

Supported parameter types in Cucumber expressions

{int}, {long}, {short}, {byte}, {float}, {double}, {bigdecimal}, {biginteger}, {word}, {string}, and the anonymous {}. Custom parameter types are not currently supported.

Run it

cd examples/going-further/example-6
mvn test