</>

Technology

Cucumber

Difficulty

Advanced

Interview Question

How do you run Cucumber tests in parallel?

Answer

Cucumber Parallel Execution

Method 1: TestNG DataProvider (Scenario-level Parallel)

Java
package runners;

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.testng.annotations.DataProvider;

@CucumberOptions(
    features = "src/test/resources/features",
    glue = {"stepDefinitions", "hooks"},
    plugin = {
        "pretty",
        "html:target/cucumber-parallel-report.html",
        "json:target/cucumber-parallel.json"
    },
    monochrome = true
)
public class ParallelTestRunner extends AbstractTestNGCucumberTests {

    @Override
    @DataProvider(parallel = true)  // ← THIS enables parallelism
    public Object[][] scenarios() {
        return super.scenarios();
    }
}

testng.xml for Thread Count

XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.9.dtd">
<suite name="Cucumber Parallel Suite" parallel="methods" thread-count="5">
    <test name="Parallel Cucumber Tests">
        <classes>
            <class name="runners.ParallelTestRunner"/>
        </classes>
    </test>
</suite>

Thread-Safe WebDriver with PicoContainer

Java
// ScenarioContext.java — new instance per scenario (PicoContainer guarantees this)
public class ScenarioContext {
    public WebDriver driver;  // each scenario gets its OWN instance
}

// Hooks.java
public class Hooks {
    private final ScenarioContext ctx;

    public Hooks(ScenarioContext ctx) { this.ctx = ctx; }

    @Before
    public void setUp() {
        WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless=new", "--no-sandbox", "--disable-dev-shm-usage");
        ctx.driver = new ChromeDriver(options);  // each thread gets its own driver
        ctx.driver.manage().window().maximize();
    }

    @After
    public void tearDown(Scenario scenario) {
        if (scenario.isFailed()) {
            byte[] screenshot = ((TakesScreenshot) ctx.driver)
                .getScreenshotAs(OutputType.BYTES);
            scenario.attach(screenshot, "image/png", "Failure");
        }
        ctx.driver.quit();
    }
}

Method 2: Feature-Level Parallel with Multiple Runners

Java
// Runner1.java — runs login.feature
@CucumberOptions(features = "src/test/resources/features/login.feature", ...)
public class Runner1 extends AbstractTestNGCucumberTests {}

// Runner2.java — runs checkout.feature
@CucumberOptions(features = "src/test/resources/features/checkout.feature", ...)
public class Runner2 extends AbstractTestNGCucumberTests {}
XML
<!-- Run both in parallel -->
<suite name="Feature Parallel" parallel="tests" thread-count="2">
    <test name="Login">
        <classes><class name="runners.Runner1"/></classes>
    </test>
    <test name="Checkout">
        <classes><class name="runners.Runner2"/></classes>
    </test>
</suite>

Method 3: Cucumber-JVM-Parallel-Plugin (Older Projects)

XML
<plugin>
    <groupId>com.github.temyers</groupId>
    <artifactId>cucumber-jvm-parallel-plugin</artifactId>
    <version>5.0.0</version>
    <executions>
        <execution>
            <goals><goal>generateRunners</goal></goals>
            <configuration>
                <parallelScheme>SCENARIO</parallelScheme>
                <glue>stepDefinitions</glue>
            </configuration>
        </execution>
    </executions>
</plugin>

Common Parallel Issues and Fixes

IssueCauseFix
Driver NullPointerExceptionSharing driver across threadsUse PicoContainer DI
Screenshots missingWrong driver referenceAlways use ctx.driver
Flaky test resultsRace condition in static fieldsRemove all static state
Report missing scenariosConcurrent file writeUse JSON + merge plugin

Merging Parallel Reports

XML
<!-- masterthought plugin merges parallel JSON reports -->
<plugin>
    <groupId>net.masterthought</groupId>
    <artifactId>maven-cucumber-reporting</artifactId>
    <version>5.8.1</version>
    <executions>
        <execution>
            <goals><goal>generate</goal></goals>
            <configuration>
                <projectName>AutomateQA</projectName>
                <outputDirectory>target/cucumber-html-reports</outputDirectory>
                <jsonFiles>
                    <param>target/**/*.json</param>
                </jsonFiles>
            </configuration>
        </execution>
    </executions>
</plugin>

Follow AutomateQA

Related Topics