Parameterize Cucumber JVM Tests with Scenario Outline and Examples
Run one Gherkin template against multiple data rows in Cucumber JVM using Scenario Outline and Examples tables.
06 Jan 2026, 15:21 UTC

Problem: duplicated scenarios for every input value
Acceptance tests often need the same checks with different inputs: valid usernames, invalid passwords, missing fields, boundary values. Writing a separate Gherkin Scenario block for each case duplicates the Given-When-Then steps and makes the feature file harder to read and maintain.
Takeaway: Use Scenario Outline with an Examples table. Cucumber JVM treats each table row as a separate scenario execution while keeping one step-definition implementation.
Prerequisites
- A Java project using Maven or Gradle.
- Cucumber JVM 6.x or 7.x. Gherkin syntax for
Scenario OutlineandExamplesis stable across these releases. - A runner class or build configuration that executes Cucumber tests.
Scenario Outline is a Gherkin template that contains angle-bracket placeholders such as <username>. Examples is a table that supplies concrete values for those placeholders. Cucumber JVM maps table columns to placeholders by header name.
Procedure: define and run a parameterized scenario
1. Add the Cucumber JVM dependency
Run this in the project root. You need read/write access to the project and permission to run the build tool.
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version><cucumber-version></version>
<scope>test</scope>
</dependency>
Replace <cucumber-version> with a 6.x or 7.x release. Risk: an unsupported version may parse Gherkin differently or fail to start the Cucumber JVM runtime.
2. Write the feature file
Create src/test/resources/login.feature:
Feature: Login validation
Scenario Outline: Invalid credentials are rejected
Given a user with username "<username>" and password "<password>"
When the user attempts to log in
Then the system returns error "<expectedError>"
Examples:
| username | password | expectedError |
| admin | wrong | Invalid password |
| unknown | secret | Unknown user |
| | secret | Username is required|
Each row in Examples executes as an independent scenario with its own lifecycle, including @Before and @After hooks.
3. Implement step definitions
Create a Java step-definition class. Cucumber expressions use {string} to capture substituted placeholder values:
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
public class LoginSteps {
private String username;
private String password;
private String actualError;
@Given("a user with username {string} and password {string}")
public void a_user_with_username_and_password(String username, String password) {
this.username = username;
this.password = password;
}
@When("the user attempts to log in")
public void the_user_attempts_to_log_in() {
// Invoke the login service with username and password.
// Capture the result in actualError.
}
@Then("the system returns error {string}")
public void the_system_returns_error(String expectedError) {
// Assert actualError equals expectedError.
}
}
Examples cells are strings. Step definitions must manually parse numbers, dates, or complex objects.
4. Run the tests
From the project root, run:
mvn test
Or, with Gradle:
gradle test
Expected check: the Cucumber report lists three scenarios for the example above, one per Examples row, even though the feature file contains one Scenario Outline.
Expected checks and diagnostics
| Check | Command or action | Expected result |
|---|---|---|
| Row expansion | Run mvn test and inspect the Cucumber report | Each Examples row appears as a distinct scenario |
| Value substitution | Change one Examples cell and add logging to the step definition | The step definition receives the changed value at runtime |
| Header mismatch | Rename a column header so it no longer matches a placeholder | The build fails during Gherkin compilation or scenario execution |
| Version check | Inspect the build file for the Cucumber JVM version | Version is 6.x or 7.x |
Limitations
- Large
Examplestables slow feedback because every row runs full setup and teardown as an independent scenario. - Placeholder names must match
Examplescolumn headers exactly; whitespace or case differences can break binding. Scenario Outlinedoes not share state between rows unless step definitions use a shared context object or dependency injection.
Recovery options
- Fix column-header mismatches so headers match placeholder names exactly.
- Parse string cells in step definitions when the test needs numbers or dates.
- Introduce a shared context object if scenarios need to read state written by a previous row.
- If the table becomes too large, move data to an external source and run fewer rows through
Scenario Outline. - Revert the feature file and step-definition changes if parameterization breaks existing test behavior.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.