Search code examples
cucumber-jvmcucumber-java

I don't know how to parallelize my test in cucumber with @cucumberOption


I have this configuration:

@RunWith(Cucumber.class)
@CucumberOptions(
         features = "src/test/resources/features",
         glue = "com.cucumberTest.stepDefinitions",
         monochrome=true,
         plugin = {
                 "html:target/cucumber-html-report",
                 "json:target/cucumber.json",
                 "pretty:target/cucumber-pretty.txt",
                 "usage:target/cucumber-usage.json",
                 "junit:target/cucumber-results.xml"
                    }

)

and I try to convert in this:

Main.main(new String[]{"--threads", "4",
                "-p","timeline:target/cucumber-parallel-report",
               "-p","json:target/prueba/cucumber.json",
                "-p","junit:target/cucumber-results.xml",
                "-p","pretty:target/cucumber-pretty.txt",
               "-p","html:target/cucumber-html-report",
                "-g", "com.cucumberTest.stepDefinitions", "src/test/resources/features/"});

but with the tag @cucumberOption. Also I am trying use the next plugin for this and I think that I get it but I want to get in the @cucumberOptions

plugin:

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.1</version>
                <configuration>
                    <testFailureIgnore>true</testFailureIgnore>
                    <parallel>both</parallel>
                    <threadCount>15</threadCount>
                </configuration>
 </plugin>

Can I get it?


Solution

  • Key Point: Before we start, would like to share a note for better understanding in future, we shall not mix direct & transitive dependencies specially their versions! Doing so can cause unpredictable outcome. Ok, let's understand things step by step.

    First - Update POM.xml with correct set of io.cucumber dependencies. We are considering v4.2.6 for this implementation

     <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>4.2.6</version>
    </dependency>
    
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-picocontainer</artifactId>
        <version>4.2.6</version>
    </dependency>
    

    Point To Note Down - There could be an issue like everything is ok but still tests do not execute in parallel and could be if your pom.xml is having direct/transitive dependency of testng. As testNG causes Surefire to ignore JUnit wrapper class. If you had testng dependency so remove the TestNG dependency or you can take a call to 2 define 2 execution - For TestNG & JUnit and disable one as per your need.

    Second - Customize Runner class as per your framework need

    package com.jacksparrow.automation.suite.runner;
    
    import org.junit.runner.RunWith;
    import cucumber.api.CucumberOptions;
    import cucumber.api.junit.Cucumber;
    
    @RunWith(Cucumber.class)
    @CucumberOptions(features = "classpath:features/functional/",
                         glue = {"com.jacksparrow.automation.steps_definitions.functional" },
                       plugin = { "pretty","json:target/cucumber-json/cucumber.json",
                                "junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
                       tags = { "@BAMS_Submitted_State_Guest_User" },
                       junit ={ "--step-notifications"},
                       strict = false,
                       dryRun = false,
                   monochrome = true)
    
    public class RunCukeTest {
    }
    

    Third - Implementing maven surefire plugin which would actually run tests in parallel

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M3</version>
        <configuration>
            <parallel>methods</parallel>
            <threadCount>2</threadCount>
            <reuserForks>false</reuserForks>
            <testFailureIgnore>true</testFailureIgnore>
            <includes>
                <include>**/*RunCukeTest.java</include>
            </includes>
        </configuration>
    </plugin>
    

    Fourth - Implement Hooks.java

    import cucumber.api.Scenario;
    import cucumber.api.java.Before;
    import cucumber.api.java.After;
    
    public class Hooks {
    
        @Before
        public void setUpScenario(String browser){
            //BaseSteps.getInstance().getBrowserInstantiation(browser); your browser setup method
        }
        @After
        public void afterScenario(Scenario scenario){
        // more code goes here  
        }
       }