You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无需过时cucumber-jvm-parallel-plugin,单Runner类用Fork并行测试可行吗?

Running Cucumber Features in Separate Maven Forks (No Deprecated Plugin Needed)

Absolutely, you can run each Cucumber feature in a separate Maven fork without relying on the deprecated cucumber-jvm-parallel-plugin. Here's a practical, modern approach using Cucumber's native integrations with JUnit 5 (or TestNG) combined with Maven Surefire's forking capabilities:

Prerequisites

  • Cucumber 7.x+ (for improved JUnit Platform/TestNG integration)
  • Maven Surefire Plugin 3.0.0+
  • JUnit 5 (preferred) or TestNG (your fallback option)

Option 1: JUnit 5 + Cucumber JUnit Platform Engine

This is the most streamlined setup, as Cucumber's JUnit Platform engine natively exposes each feature as a distinct test "class" that Surefire can split into forks.

Step 1: Update Dependencies

Add these to your pom.xml:

<dependencies>
    <!-- Cucumber Core -->
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>7.14.0</version>
        <scope>test</scope>
    </dependency>
    <!-- Cucumber-JUnit 5 Integration -->
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-junit-platform-engine</artifactId>
        <version>7.14.0</version>
        <scope>test</scope>
    </dependency>
    <!-- JUnit 5 Suite & Engine -->
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-suite-api</artifactId>
        <version>1.10.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Step 2: Create a Single Suite Runner

Instead of multiple runners, make one suite that includes all your features:

import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;

import static io.cucumber.junit.platform.engine.Constants.FEATURES_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;

@Suite
@IncludeEngines("cucumber")
@SelectPackages("com.your.project.steps") // Path to your step definitions
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.your.project.steps")
@ConfigurationParameter(key = FEATURES_PROPERTY_NAME, value = "src/test/resources/features") // Path to your .feature files
public class CucumberTestSuite {}

Step 3: Configure Surefire for Forked Execution

Tell Surefire to split features across separate JVM forks by targeting the "classes" level (each feature is treated as a class by the JUnit Platform engine):

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.2.2</version>
            <configuration>
                <parallel>classes</parallel> <!-- Split by Cucumber features (exposed as classes) -->
                <forkCount>4</forkCount> <!-- Number of parallel JVM forks (match your feature count or desired parallelism) -->
                <reuseForks>true</reuseForks> <!-- Reuse forks to speed up execution (set to false for fresh JVMs every time) -->
                <systemPropertyVariables>
                    <cucumber.plugin>pretty,html:target/cucumber-reports</cucumber.plugin>
                </systemPropertyVariables>
            </configuration>
        </plugin>
    </plugins>
</build>

Option 2: TestNG Alternative

If you prefer to stick with TestNG, use Cucumber's TestNG integration to expose each feature as a separate test, then configure Surefire to fork these tests.

Step 1: Update Dependencies

Add TestNG-specific Cucumber dependencies:

<dependencies>
    <!-- Cucumber TestNG Integration -->
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-testng</artifactId>
        <version>7.14.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.8.0</version>
        <scope>test</scope>
    </dependency>
    <!-- Keep your existing Cucumber core dependency -->
</dependencies>

Step 2: Create a TestNG Runner

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;

@CucumberOptions(
        features = "src/test/resources/features",
        glue = "com.your.project.steps",
        plugin = {"pretty", "html:target/cucumber-reports"}
)
public class CucumberTestNGSuite extends AbstractTestNGCucumberTests {}

Step 3: Configure Surefire & TestNG

Create a testng.xml file:

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Cucumber Suite" parallel="tests" thread-count="4">
    <test name="Cucumber Features">
        <classes>
            <class name="com.your.project.CucumberTestNGSuite"/>
        </classes>
    </test>
</suite>

Update Surefire in pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.2.2</version>
    <configuration>
        <parallel>tests</parallel> <!-- Split by individual Cucumber features (exposed as TestNG tests) -->
        <forkCount>4</forkCount> <!-- Number of parallel JVM forks -->
        <reuseForks>true</reuseForks>
        <suiteXmlFiles>
            <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
        </suiteXmlFiles>
    </configuration>
</plugin>

Verify Execution

Run mvn test and check the logs—you'll see lines indicating each feature starts in a separate JVM fork (look for Forking command line: entries). Each feature runs in complete isolation, just like with the deprecated plugin.

内容的提问来源于stack exchange,提问作者VladislavShcherba

火山引擎 最新活动