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.