Running feature files in parallel from Java in Cucumber 4

Introduction

Cucumber-JVM 4 supports parallel execution across threads out of the box. This article describes how to use this technique to run features directly from Java code inside a main, JUnit or TestNG method. This makes use of the main() method of the Main class contained in the cucumber.api.cli package. The main() method executes the feature files directly without the use of a runner. The options that need to be passed as a String[] to the main() method are described here.

Source Code

The source code is located here.

Command

The one line command that triggers the running of the feature files is mentioned below. For a detailed overview of all the available options and format refer here and Java files with the below command.

Main.main(new String[]{ “–threads”,  “4”, “-p”, “timeline:target/cucumber-parallel-report”, “-g”, “stepdef”, “src/test/resources/features/parallel/”});

Brief description of the options in the above code –

  • –threads   —  Runs the scenarios in parallel. Value is the number of threads. Default is 1.
  • -p            —  Register a plugin. To register multiple plugins repeat “-p” declaration.
  • -g            —  Path to the step definition code as a Java package structure.
  • -t             — Run scenarios that match the tag expression. (Not shown in this command)
  • [features]  — Needs to be the last option. Path to the feature file. Either directory or a specific file.

This command can be used inside a main() method of a class. Also can be used inside a test method of a JUnit or TestNG test class.

This can be used in previous versions of Cucumber other than the ‘–threads’ option which was introduced in Cucumber 4.

Parallel Execution

To achieve parallel execution the “–threads” option needs a value more than 1. This is the count of the number of threads. All the steps of a single scenario will be executed by a single thread. In case of a scenariooutline all the steps of an example will be executed by a single thread.

parallel1.feature, parallel2.feature, parallel3.feature, stepdefinition.java

Feature: Feature 1

Scenario: Scenario 1
  Given the details from parallel1 are 111
  Given the details from parallel1 are 112

Scenario: Scenario 2
  Given the details from parallel1 are 121
  Given the details from parallel1 are 122
Feature: Feature 2

Scenario: Scenario 1
  Given the details from parallel2 are 211
  Given the details from parallel2 are 212

Scenario: Scenario 2
  Given the details from parallel2 are 221
  Given the details from parallel2 are 222
Feature: Feature 3

Scenario Outline: ScenarioOutline 1
  Given the details from parallel3step1 are <num>
  Given the details from parallel3step2 are <num>

    Examples:
    | num |
    | 1 |
    | 2 |
    | 3 |
@Given("the details from {word} are {int}")
public void parallelstep(String file, int num) {
    System.out.println(Thread.currentThread().getId()+" - "+file+" - "+num);
}
 1.  14 - parallel2 - 221
 2.  13 - parallel2 - 211
 3.  11 - parallel1 - 111
 4.  12 - parallel1 - 121
 5.  13 - parallel2 - 212
 6.  14 - parallel2 - 222
 7.  14 - parallel3step1 - 2
 8.  14 - parallel3step2 - 2
 9.  12 - parallel1 - 122
10.  12 - parallel3step1 - 3
11.  12 - parallel3step2 - 3
12.  11 - parallel1 - 112
13.  13 - parallel3step1 - 1
14.  13 - parallel3step2 - 1

From the console print statements of the execution, ‘Scenario 1’ of ‘Feature 1’ is run by the thread id of 11 (Line 3 & 12). Likewise ‘Scenario 2’ of ‘Feature 1’ is run by thread id of 12 (Line 4 & 9). For the ScenarioOutline, the first row is run by thread id of 13 (Line 13 & 14). Similarly other steps of scenarios can also be mapped to same thread ids.

TimeLineFormatter

To get a visual representation of the threads in actions, one can use the TimeLineFormatter plugin. Just add the “timeline:target dir” to the “-p” option to generate the report. The timeline format of the threads of the above case is displayed below. For the actual report refer here.