How to Share data between Steps in Cucumber using Scenario Context

  

In CucumberScenario 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 keys

package utils;

public enum Context {
    USER_NAME,
    PRODUCT_NAME,
    ORDER_ID
}




2. ScenarioContext.java — Storage class

package 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



No comments:

Post a Comment