Passing data between steps in Cucumber
Posted on
When writing test automation using Cucumber, you often need to pass data from one step to another. Cucumber doesn't store data between steps automatically, but you can achieve this using instance variables, dependency injection and Scenario Context.
Approach 1: Using Instance Variables
The easiest way to share data between steps is by using instance variables inside a step definition class.
Java
Copy
public class LoginSteps { private String username; @Given("User enters username {string}") public void userEntersUsername(String username) { this.username = username; // Store data in instance variable } @When("User logs in") public void userLogsIn() { System.out.println("Logging in with username: " + username); } @Then("User should see their profile") public void userShouldSeeProfile() { System.out.println("Verifying profile for user: " + username); } }
Approach 2: Using Scenario Context
Step 1: Create Scenario Context Class
Java
Copy
import java.util.HashMap; import java.util.Map; public class ScenarioContext { private Map<String, Object> data = new HashMap<>(); public void setData(String key, Object value) { data.put(key, value); } public Object getData(String key) { return data.get(key); } }
Step 2: Use Scenario Context in Step Definitions
Java
Copy
public class LoginSteps { private ScenarioContext scenarioContext; // Constructor-based Dependency Injection public LoginSteps(ScenarioContext scenarioContext) { this.scenarioContext = scenarioContext; } @Given("User enters username {string}") public void userEntersUsername(String username) { scenarioContext.setData("username", username); } @When("User logs in") public void userLogsIn() { String username = (String) scenarioContext.getData("username"); System.out.println("Logging in with username: " + username); } @Then("User should see their profile") public void userShouldSeeProfile() { String username = (String) scenarioContext.getData("username"); System.out.println("Verifying profile for user: " + username); } }
Approach 3: Using Dependency Injection with PicoContainer
If you use PicoContainer, you don’t need to manually create ScenarioContext. Instead, Cucumber automatically injects dependencies.
Step 1: Define a Shared Class
Java
Copy
public class SharedData { private String username; public void setUsername(String username) { this.username = username; } public String getUsername() { return username; } }
Step 2: Inject SharedData into Step Definitions
Java
Copy
public class LoginSteps { private final SharedData sharedData; // PicoContainer automatically injects this public LoginSteps(SharedData sharedData) { this.sharedData = sharedData; } @Given("User enters username {string}") public void userEntersUsername(String username) { sharedData.setUsername(username); } @When("User logs in") public void userLogsIn() { System.out.println("Logging in with username: " + sharedData.getUsername()); } @Then("User should see their profile") public void userShouldSeeProfile() { System.out.println("Verifying profile for user: " + sharedData.getUsername()); } }