How to Share Test Context between Cucumber Step Definitions

Sharing test context between step definitions in Cucumber is a common practice when multiple step definition classes need to share state, such as:

  • WebDriver instance

  • Page Objects

  • Test data


Why Share Context?

Each step definition class is instantiated independently by Cucumber. So if you define a variable in one step class, it won’t be accessible in another unless you explicitly share it.


Solution: Use a Shared Context or Dependency Injection

There are two common ways:

1. Create a Context Class

A simple POJO class to hold shared data (like WebDriver, test data, etc.)

2. Use Constructor Injection in Step Definition Classes

Pass the shared context to all step classes via their constructors.


Example: Sharing WebDriver using TestContext class

Step 1: Create TestContext Class

package utils;

import org.openqa.selenium.WebDriver;

public class TestContext {
    private WebDriver driver;

    public void setDriver(WebDriver driver) {
        this.driver = driver;
    }

    public WebDriver getDriver() {
        return driver;
    }
}




Step 2: Base Step Definition Constructor

package stepDefinitions;

import utils.TestContext;

public class BaseSteps {
    protected TestContext context;

    public BaseSteps(TestContext context) {
        this.context = context;
    }
}




Step 3: Step Definitions Using Shared Context

LoginSteps.java

package stepDefinitions;

import io.cucumber.java.en.Given;
import org.openqa.selenium.chrome.ChromeDriver;
import utils.TestContext;

public class LoginSteps extends BaseSteps {

    public LoginSteps(TestContext context) {
        super(context);
    }

    @Given("User launches the application")
    public void user_launches_the_application() {
        context.setDriver(new ChromeDriver());
        context.getDriver().get("https://example.com");
    }
}




HomeSteps.java

package stepDefinitions;

import io.cucumber.java.en.Then;
import utils.TestContext;

public class HomeSteps extends BaseSteps {

    public HomeSteps(TestContext context) {
        super(context);
    }

    @Then("User should see the homepage")
    public void user_should_see_homepage() {
        String title = context.getDriver().getTitle();
        System.out.println("Title: " + title);
    }
}




Step 4: Create TestContextInitializer to Inject Context

package stepDefinitions;

import io.cucumber.java.Before;
import utils.TestContext;

public class TestContextInitializer {
    private static final TestContext context = new TestContext();

    public static TestContext getContext() {
        return context;
    }

    @Before
    public void beforeScenario() {
        // You can initialize default values here if needed
    }
}




Step 5: Update Step Definitions to Use Shared Context

To use the shared context in your step definitions, make sure to pass the same instance:

public class LoginSteps extends BaseSteps {
    public LoginSteps() {
        super(TestContextInitializer.getContext());
    }
}


Benefits

  • Clean separation of logic and context

  • Easily extensible

  • Promotes reuse of WebDriver, data, and page objects

No comments:

Post a Comment