In Cucumber, Scenario Context is a way to share data between step definitions during the execution of a single scenario. Since each scenario is stateless and Cucumber creates a new instance of step definition classes for each scenario, sharing data between steps requires an intermediate storage — Scenario Context.
Why use Scenario Context?
To avoid using static variables (which breaks parallel execution).
To maintain clean separation of concerns in step definitions.
To store and retrieve test data like user credentials, page titles, order IDs, etc.
Implementation Steps
We will:
- Create an enum for keys (
Context). - Create a ScenarioContext class to hold data.
- Inject and use ScenarioContext in step definition classes.
1.
Context.java — Enum for keyspackage utils; public enum Context { USER_NAME, PRODUCT_NAME, ORDER_ID }
2.
ScenarioContext.java — Storage classpackage utils; import java.util.HashMap; import java.util.Map; public class ScenarioContext { private final Map<String, Object> dataMap = new HashMap<>(); public void setContext(Context key, Object value) { dataMap.put(key.toString(), value); } public Object getContext(Context key) { return dataMap.get(key.toString()); } public Boolean contains(Context key) { return dataMap.containsKey(key.toString()); } }
3.
TestContext.java — Shared container (optional but recommended for larger projects)package utils; public class TestContext { private final ScenarioContext scenarioContext; public TestContext() { scenarioContext = new ScenarioContext(); } public ScenarioContext getScenarioContext() { return scenarioContext; } }
4. Step Definition Example — Using Scenario Context
package stepDefinitions; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import utils.Context; import utils.TestContext; public class UserSteps { TestContext testContext; public UserSteps(TestContext context) { this.testContext = context; } @Given("User logs in with username {string}") public void user_logs_in_with_username(String username) { System.out.println("User logged in: " + username); testContext.getScenarioContext().setContext(Context.USER_NAME, username); } @Then("User name should be displayed on dashboard") public void user_name_should_be_displayed_on_dashboard() { String actualUsername = (String) testContext.getScenarioContext().getContext(Context.USER_NAME); System.out.println("Username on dashboard: " + actualUsername); // Add assertions here } }
5. Cucumber Runner Setup
Ensure you pass the same TestContext object to all step definition classes.
If you are using Dependency Injection (like PicoContainer or Spring), Cucumber will manage the object sharing automatically.
package stepDefinitions; import utils.TestContext; public class Hooks { public Hooks(TestContext testContext) { // You can use this to perform Before/After actions using shared context } }
Sample Feature File
Feature: Scenario Context Demo Scenario: Store and use data between steps Given User logs in with username "Himanshu" Then User name should be displayed on dashboard
Output
User logged in: Himanshu Username on dashboard: Himanshu