Q10 of 21 · BDD / Cucumber
How do you share state between step definitions in Cucumber without using static variables?
BDD / CucumberMidbddcucumberstate-sharingdependency-injectionworldpicocontainer
Short answer
Short answer: In Java, use dependency injection (PicoContainer, Spring, Guice) to inject a shared context object into each step definition class. In JavaScript, use the World object (this) which Cucumber creates per scenario.
Detail
Step definitions are often split across multiple classes/files. Sharing state between them needs a mechanism that's scoped to the scenario (not global or static).
Java — PicoContainer DI (simplest):
// Shared context class
public class TestContext {
public String authToken;
public String lastCreatedOrderId;
}
// Step def 1
public class LoginSteps {
private final TestContext ctx;
public LoginSteps(TestContext ctx) { this.ctx = ctx; }
@When("the user logs in")
public void userLogsIn() {
ctx.authToken = api.login("user@example.com", "pass");
}
}
// Step def 2 — same ctx instance, injected by PicoContainer
public class OrderSteps {
private final TestContext ctx;
public OrderSteps(TestContext ctx) { this.ctx = ctx; }
@When("the user creates an order")
public void createOrder() {
api.setToken(ctx.authToken);
ctx.lastCreatedOrderId = api.createOrder();
}
}
PicoContainer creates one TestContext per scenario automatically — no extra config needed.
JavaScript — World object:
// setWorldConstructor to define the World shape
const { setWorldConstructor, Before } = require('@cucumber/cucumber');
class CustomWorld {
constructor() {
this.authToken = null;
this.page = null;
}
}
setWorldConstructor(CustomWorld);
// In any step definition, 'this' is the World instance for that scenario
When('the user logs in', async function() {
this.authToken = await api.login('user@example.com', 'pass');
});
Why not static variables? Static state persists across scenarios and is not thread-safe — parallel runs will corrupt each other's data.
// WHAT INTERVIEWERS LOOK FOR
DI (PicoContainer/Spring) for Java, World for JS. Why statics are dangerous in parallel execution. Per-scenario scope.
// COMMON PITFALL
Using static fields to share state — causes test pollution and non-deterministic failures in parallel execution.