Answer
Passing Data Between Scenarios in Cucumber
The Problem
In Cucumber, each Scenario runs in isolation — this is by design. You cannot directly share state between scenarios because Cucumber intentionally isolates them.
Gherkin
-- You CANNOT directly do this:
Scenario: Generate token
When I call the auth API
Then I store the token ← token created here
Scenario: Use token
Given I use the token from previous scenario ← this will NOT work
When I call protected API
Why Isolation Matters
Scenarios should be:
- ✓Independent — run in any order, run individually
- ✓Idempotent — same result every time
- ✓Reproducible — pass/fail without depending on other tests
Solutions for Sharing Data
Solution 1: Dependency Injection with PicoContainer (Recommended)
Share state within a feature using a shared World context object:
XML
<!-- pom.xml -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>7.15.0</version>
</dependency>
Java
// Shared context class
public class TestContext {
public String authToken;
public String userId;
public String orderId;
}
// Step definition that SETS data
public class AuthSteps {
private TestContext context;
public AuthSteps(TestContext context) { // PicoContainer injects
this.context = context;
}
@When("I authenticate with the API")
public void authenticate() {
String token = apiClient.getToken("user", "pass");
context.authToken = token; // ← stored in shared context
}
}
// Step definition that USES data
public class OrderSteps {
private TestContext context;
public OrderSteps(TestContext context) { // same instance injected
this.context = context;
}
@When("I create an order")
public void createOrder() {
// Uses token set by AuthSteps (within same scenario)
apiClient.createOrder(context.authToken, orderData);
}
}
Solution 2: Static Variables (Simple but Risky)
Java
public class SharedState {
public static String authToken;
public static String userId;
}
// Setter step
@When("I authenticate")
public void authenticate() {
SharedState.authToken = apiClient.login("user", "pass");
}
// Getter step (different scenario)
@Given("I am authenticated")
public void useToken() {
apiClient.setToken(SharedState.authToken);
}
Warning: Static variables persist across scenarios — parallel execution will cause race conditions.
Solution 3: External Storage (Database / File / Redis)
Java
// Write token to file
@After
public void saveToken(Scenario scenario) {
if (scenario.getName().contains("Generate Token")) {
Files.write(Paths.get("token.txt"), authToken.getBytes());
}
}
// Read token from file
@Before
public void loadToken(Scenario scenario) {
if (scenario.getName().contains("Use Token")) {
authToken = new String(Files.readAllBytes(Paths.get("token.txt")));
}
}
Best Practice: Redesign to Avoid Cross-Scenario Dependency
Gherkin
-- BETTER: Each scenario is self-contained
Scenario: Create and use order in one flow
Given I am authenticated as "customer" ← sets up everything needed
When I create an order for "Laptop"
Then the order should be in my order history
Use API calls in @Before hooks to set up preconditions rather than depending on other scenarios.
