Cucumber-JVM allows parallel execution across multiple threads since version 4.0.0.
There are several options to incorporate this built-in feature in a Cucumber project. You can do so using:
For each of these options, this tutorial will look at the project setup, configuration settings and execution commands.
Cucumber-JVM allows parallel execution across multiple threads since version 4.0.0.
There are several options to incorporate this built-in feature in a Cucumber project. You can do so using:
For each of these options, this tutorial will look at the project setup, configuration settings and execution commands.
JUnit 5
Cucumber Scenarios can be executed in parallel using the JUnit Platform.
See the cucumber-junit-platform-engine documentation for details.
Cucumber Scenarios can be executed in parallel using the JUnit Platform.
See the cucumber-junit-platform-engine documentation for details.
JUnit 4
Cucumber can be executed in parallel using JUnit and Maven test execution plugins. In JUnit the feature files are run in parallel rather than scenarios, which means all the scenarios in a feature file will be executed by the same thread. You can use either Maven Surefire or Failsafe plugin to execute the runners.
Create a Maven project in your favorite IDE using the cucumber-archetype or by adding Cucumber dependencies to the POM as detailed here and Junit dependencies here.
Create a parallel folder (or any other name) in
src/test/resources
path and add the two feature files (scenarios.feature
andscenario-outlines.feature
) inside it.
Feature: Scenarios feature file
Scenario: Scenario Number One
Given Step from 'Scenario 1' in 'scenarios' feature file
Scenario: Scenario Number Two
Given Step from 'Scenario 2' in 'scenarios' feature file
Feature: Scenario Outlines feature file
Scenario Outline: <scen_out_row_num>
Given Step from '<scen_out_row_num>' in 'scenario-outlines' feature file
Examples:
| scen_out_row_num |
| Scenario Outline Row 1 |
| Scenario Outline Row 2 |
Cucumber can be executed in parallel using JUnit and Maven test execution plugins. In JUnit the feature files are run in parallel rather than scenarios, which means all the scenarios in a feature file will be executed by the same thread. You can use either Maven Surefire or Failsafe plugin to execute the runners.
Create a Maven project in your favorite IDE using the cucumber-archetype or by adding Cucumber dependencies to the POM as detailed here and Junit dependencies here.
Create a parallel folder (or any other name) in
src/test/resources
path and add the two feature files (scenarios.feature
andscenario-outlines.feature
) inside it.
Feature: Scenarios feature file
Scenario: Scenario Number One
Given Step from 'Scenario 1' in 'scenarios' feature file
Scenario: Scenario Number Two
Given Step from 'Scenario 2' in 'scenarios' feature file
Feature: Scenario Outlines feature file
Scenario Outline: <scen_out_row_num>
Given Step from '<scen_out_row_num>' in 'scenario-outlines' feature file
Examples:
| scen_out_row_num |
| Scenario Outline Row 1 |
| Scenario Outline Row 2 |
- Add the step definition class to the
parallel
package (same name as folder above for automatic pickup by runner) insrc/test/java
folder.
package parallel;
import io.cucumber.java.BeforeStep;
import io.cucumber.java.en.Given;
public class StepDefs {
@Given("Step from {string} in {string} feature file")
public void step(String scenario, String file) {
System.out.format("Thread ID - %2d - %s from %s feature file.\n",
Thread.currentThread().getId(), scenario,file);
}
}
- Add the step definition class to the
parallel
package (same name as folder above for automatic pickup by runner) insrc/test/kotlin
folder.
package parallel
import io.cucumber.java8.En
class StepDefs : En {
init {
Given("Step from {string} in {string} feature file") { scenario: String , file: String ->
println("Thread ID - ${Thread.currentThread().id} - $scenario from $file feature file")
}
}
}
- Add a cucumber runner using the
RunWith
annotation in theparallel
package (same name as step definition package) in thesrc/test/java
folder.
- Add a cucumber runner using the
RunWith
annotation in theparallel
package (same name as step definition package) in thesrc/test/kotlin
folder.
package parallel;
import io.cucumber.junit.Cucumber;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
public class RunCucumberTest {
}
package parallel
import io.cucumber.junit.Cucumber
import org.junit.runner.RunWith
@RunWith(Cucumber::class)
class RunCucumberTest
- Add the Surefire plugin configuration to the
build
section to thePOM
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<parallel>methods</parallel>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>
</plugin>
- Use the Maven
install
or a suitable command to execute thePOM
. This should run in parallel threaded mode. You should see a result similar to below. It is important to note that both the scenarios in the file (scenarios.feature
) are executed by thread with ID 14. Similarly both the rows of the scenario outline in the file (scenario-outlines.feature
) are executed by thread with ID 13.
Thread ID - 13 - Scenario Outline Row 1 from scenario-outlines feature file.
Thread ID - 13 - Scenario Outline Row 2 from scenario-outlines feature file.
Thread ID - 14 - Scenario 1 from scenarios feature file.
Thread ID - 14 - Scenario 2 from scenarios feature file.
- To execute using a Maven Failsafe plugin include the below configuration in the
build
section to thePOM
. Rename the runner class toRunCucumberIT
. You can find further details here.
For Failsafe to find your step definitions, make sure they are in src/test/java.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.0</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<parallel>methods</parallel>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>
</execution>
</executions>
</plugin>
To set the thread count to a specific number instead of useUnlimitedThreads
use the below setting.
<configuration>
<parallel>methods</parallel>
<threadCount>4</threadCount>
</configuration>
The thread count in the above setting is 4 threads per core. If you want this to be 4 threads across all cores set the perCoreThreadCount
to false.
<configuration>
<parallel>methods</parallel>
<threadCount>4</threadCount>
<perCoreThreadCount>false</perCoreThreadCount>
</configuration>
In case of multiple runners one can also set the parallel option to classesAndMethods
or classes
in addition to methods
.
<configuration>
<parallel>classesAndMethods</parallel>
useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>
- Add the Surefire plugin configuration to the
build
section to thePOM
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<parallel>methods</parallel>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>
</plugin>
- Use the Maven
install
or a suitable command to execute thePOM
. This should run in parallel threaded mode. You should see a result similar to below. It is important to note that both the scenarios in the file (scenarios.feature
) are executed by thread with ID 14. Similarly both the rows of the scenario outline in the file (scenario-outlines.feature
) are executed by thread with ID 13.
Thread ID - 13 - Scenario Outline Row 1 from scenario-outlines feature file.
Thread ID - 13 - Scenario Outline Row 2 from scenario-outlines feature file.
Thread ID - 14 - Scenario 1 from scenarios feature file.
Thread ID - 14 - Scenario 2 from scenarios feature file.
- To execute using a Maven Failsafe plugin include the below configuration in the
build
section to thePOM
. Rename the runner class toRunCucumberIT
. You can find further details here.
For Failsafe to find your step definitions, make sure they are in src/test/java.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.0</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<parallel>methods</parallel>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>
</execution>
</executions>
</plugin>
To set the thread count to a specific number instead of useUnlimitedThreads
use the below setting.
<configuration>
<parallel>methods</parallel>
<threadCount>4</threadCount>
</configuration>
The thread count in the above setting is 4 threads per core. If you want this to be 4 threads across all cores set the perCoreThreadCount
to false.
<configuration>
<parallel>methods</parallel>
<threadCount>4</threadCount>
<perCoreThreadCount>false</perCoreThreadCount>
</configuration>
In case of multiple runners one can also set the parallel option to classesAndMethods
or classes
in addition to methods
.
<configuration>
<parallel>classesAndMethods</parallel>
useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>
TestNG
Cucumber can be executed in parallel using TestNG and Maven test execution plugins by setting the dataprovider parallel option to true. In TestNG the scenarios and rows in a scenario outline are executed in multiple threads. One can use either Maven Surefire or Failsafe plugin for executing the runners.
Cucumber can be executed in parallel using TestNG and Maven test execution plugins by setting the dataprovider parallel option to true. In TestNG the scenarios and rows in a scenario outline are executed in multiple threads. One can use either Maven Surefire or Failsafe plugin for executing the runners.
- Add a cucumber runner by extending the
AbstractTestNGCucumberTests
class and overriding the scenarios method in theparallel
package (same name as step definition package) insrc/test/java
folder. Set the parallel option value to true for the DataProvider annotation.
package parallel;
import org.testng.annotations.DataProvider;
import io.cucumber.testng.AbstractTestNGCucumberTests;
public class RunCucumberTest extends AbstractTestNGCucumberTests{
@Override
@DataProvider(parallel = true)
public Object[][] scenarios() {
return super.scenarios();
}
}
- Add a cucumber runner by extending the
AbstractTestNGCucumberTests
class and overriding the scenarios method in theparallel
package (same name as step definition package) insrc/test/kotlin
folder. Set the parallel option value to true for the DataProvider annotation.
package parallel
import org.testng.annotations.DataProvider;
import io.cucumber.testng.AbstractTestNGCucumberTests;
class RunCucumberTest : AbstractTestNGCucumberTests() {
@DataProvider(parallel = true)
override fun scenarios(): Array<Array<(Any)>> {
return super.scenarios()
}
}
- Add the Maven Surefire plugin configuration to the
build
section of thePOM
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
- Use the Maven
install
or a suitable command to execute the POM. This should run in parallel thread mode. You should see a result similar to below. The scenarios and rows of the scenario outlines are executed in different threads.
Thread ID - 15 - Scenario Outline Row 2 from scenario-outlines feature file.
Thread ID - 14 - Scenario Outline Row 1 from scenario-outlines feature file.
Thread ID - 16 - Scenario 1 from scenarios feature file.
Thread ID - 17 - Scenario 2 from scenarios feature file.
- To execute using a Maven Failsafe plugin, setup the
POM
as described in the JUnit section. Remove theparallel
anduseUnlimitedThreads
settings in theconfiguration
part.
The default thread count of the dataprovider in parallel mode is 10. To change this the dataproviderthreadcount
property needs to be added to the configuration
section of the Surefire or Failsafe plugin in the POM
.
<configuration>
<properties>
<property>
<name>dataproviderthreadcount</name>
<value>20</value>
</property>
</properties>
</configuration>
If you have multiple runners, set the parallel configuration to classes
to reduce execution times. In addition the threadCount
can be set to to the desired value or useUnlimitedThreads
can be set to true.
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>
- Add the Maven Surefire plugin configuration to the
build
section of thePOM
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
- Use the Maven
install
or a suitable command to execute the POM. This should run in parallel thread mode. You should see a result similar to below. The scenarios and rows of the scenario outlines are executed in different threads.
Thread ID - 15 - Scenario Outline Row 2 from scenario-outlines feature file.
Thread ID - 14 - Scenario Outline Row 1 from scenario-outlines feature file.
Thread ID - 16 - Scenario 1 from scenarios feature file.
Thread ID - 17 - Scenario 2 from scenarios feature file.
- To execute using a Maven Failsafe plugin, setup the
POM
as described in the JUnit section. Remove theparallel
anduseUnlimitedThreads
settings in theconfiguration
part.
The default thread count of the dataprovider in parallel mode is 10. To change this the dataproviderthreadcount
property needs to be added to the configuration
section of the Surefire or Failsafe plugin in the POM
.
<configuration>
<properties>
<property>
<name>dataproviderthreadcount</name>
<value>20</value>
</property>
</properties>
</configuration>
If you have multiple runners, set the parallel configuration to classes
to reduce execution times. In addition the threadCount
can be set to to the desired value or useUnlimitedThreads
can be set to true.
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>
CLI
The Main
class in the io.cucumber.core.cli
package is used to execute the feature files. You can run this class directly from the command line; in that case, there is no need to create any runner class. The usage options for this class are mentioned here. The --threads
option needs to be set to a value greater than 1 to run in parallel. When the parallel mode is used, the scenarios and rows in a scenario outline will be run in multiple threads.
Follow the steps below to execute the command from a terminal.
Add the two feature files (
scenarios.feature
andscenario-outlines.feature
) and step definition class as described in the JUnit section.Open up a terminal window and navigate to the source folder of the project, in this case parallel.
The Main
class in the io.cucumber.core.cli
package is used to execute the feature files. You can run this class directly from the command line; in that case, there is no need to create any runner class. The usage options for this class are mentioned here. The --threads
option needs to be set to a value greater than 1 to run in parallel. When the parallel mode is used, the scenarios and rows in a scenario outline will be run in multiple threads.
Follow the steps below to execute the command from a terminal.
Add the two feature files (
scenarios.feature
andscenario-outlines.feature
) and step definition class as described in the JUnit section.Open up a terminal window and navigate to the source folder of the project, in this case parallel.
- Compile the step definition class. Add the path to the folder containing cucumber jars to the classpath using the -cp option.
javac -cp .;<path to cucumber jar folder>/* ./parallel/StepDefs.java
- Compile the step definition class. Add path to each of the downloaded cucumber jars to the classpath using the -cp option.
kotlinc -cp .;<path to each cucumber jar> -jvm-target 1.8 ./parallel/StepDefs.kt
- Execute using the below command.
- Execute using the below command.
java -cp .;<path to cucumber jar folder>/* io.cucumber.core.cli.Main --threads 4 -g parallel parallel
java -cp .;<path to cucumber jar folder>/*;<path to kotlin lib folder>/* io.cucumber.core.cli.Main --threads 4 -g parallel parallel
- You should get a console output similar to below.
Thread ID - 11 - Scenario Outline Row 1 from scenario-outlines feature file.
Thread ID - 14 - Scenario 2 from scenarios feature file.
Thread ID - 12 - Scenario Outline Row 2 from scenario-outlines feature file.
Thread ID - 13 - Scenario 1 from scenarios feature file.
- You should get a console output similar to below.
Thread ID - 11 - Scenario Outline Row 1 from scenario-outlines feature file.
Thread ID - 14 - Scenario 2 from scenarios feature file.
Thread ID - 12 - Scenario Outline Row 2 from scenario-outlines feature file.
Thread ID - 13 - Scenario 1 from scenarios feature file.
Timeline Formatter
For a visual representation of threads, add the timeline report using the plugin
option of CucumberOptions
annotation on a JUnit or TestNG runner.
For a visual representation of threads, add the timeline report using the plugin
option of CucumberOptions
annotation on a JUnit or TestNG runner.
@CucumberOptions(plugin= {"timeline:<report folder>"})
@CucumberOptions(plugin = ["timeline:<report folder>"])
In case of CLI, the below command can be used.
java -cp <classpath> io.cucumber.core.cli.Main -p timeline:<report folder> --threads <thread count> -g <steps package> <path to feature files>
Below is a sample report.
In case of CLI, the below command can be used.
java -cp <classpath> io.cucumber.core.cli.Main -p timeline:<report folder> --threads <thread count> -g <steps package> <path to feature files>
Below is a sample report.