Tom
Tom

Reputation: 1105

Cucumber - running parallel scenarios

I have a test in Cucumber which is using the Example Table format. Could I get Cucumber to run each line of the table in parallel.

Scenario Outline: e_5_1 Check Convicting Court Codes in English 2

Given I navigate to the customer portal search screen
When I enter DLN, NI and Postcode from row <user_row> and access Penalties and disqualifications
And click on the endorsement in order to confirm court description from rows <row1> to <row2>

Then I Logout

  Examples:
    | user_row  | row1      | row2      |
    |   2       |   2       |   51      |
    |   52      |   52      |   98      |
    |   99      |   99      |   148     |
    |   149     |   149     |   198     |

Normally, I would say run test.feature for the line number and it would iterate through each row one at a time, or using the line number I could specify in which line the table row sits.

Could I get it to run all 4 rows in parallel at the same time?

Thanks in advance

Upvotes: 0

Views: 940

Answers (2)

Sugat Mankar
Sugat Mankar

Reputation: 478

You can use opensource plugin cucumber-jvm-parallel-plugin which has many advantages over existing solutions but its only for java. Available at maven repository

   <dependency>
     <groupId>com.github.temyers</groupId>
     <artifactId>cucumber-jvm-parallel-plugin</artifactId>
     <version>2.2.0</version>
   </dependency>
  1. First you need to add this dependency and plugin with required configuration in your project pom file.

     <dependencies>
        <dependency>
         <groupId>com.github.temyers</groupId>
         <artifactId>cucumber-jvm-parallel-plugin</artifactId>
         <version>2.2.0</version>
       </dependency>
       <dependency>
          <groupId>net.masterthought</groupId>
          <artifactId>cucumber-reporting</artifactId>
          <version>3.3.0</version>
       </dependency>
    </dependencies>
    
    <plugin>
      <groupId>com.github.temyers</groupId>
      <artifactId>cucumber-jvm-parallel-plugin</artifactId>
      <version>2.2.0</version>
      <executions>
         <execution>
         <id>generateRunners</id>
         <phase>generate-test-sources</phase>
         <goals>
           <goal>generateRunners</goal>
         </goals>
         <configuration>
             <!-- Mandatory -->
             <!-- comma separated list of package names to scan for glue code -->
             <glue>foo, bar</glue>
             <outputDirectory>${project.build.directory}/generated-test-sources/cucumber</outputDirectory>
              <!-- The directory, which must be in the root of the runtime classpath, containing your feature files.  -->
               <featuresDirectory>src/test/resources/features/</featuresDirectory>
              <!-- Directory where the cucumber report files shall be written  -->
              <cucumberOutputDir>target/cucumber-parallel</cucumberOutputDir>
              <!-- comma separated list of output formats json,html,rerun.txt -->
              <format>json</format>
              <!-- CucumberOptions.strict property -->
              <strict>true</strict>
              <!-- CucumberOptions.monochrome property -->
              <monochrome>true</monochrome>
              <!-- The tags to run, maps to CucumberOptions.tags property you can pass ANDed tags like "@tag1","@tag2" and ORed tags like "@tag1,@tag2,@tag3" -->
             <tags></tags>
             <!-- If set to true, only feature files containing the required tags shall be generated. -->
             <filterFeaturesByTags>false</filterFeaturesByTags>
             <!-- Generate TestNG runners instead of default JUnit ones. --> 
             <useTestNG>false</useTestNG>
             <!-- The naming scheme to use for the generated test classes.  One of 'simple' or 'feature-title' --> 
            <namingScheme>simple</namingScheme>
            <!-- The class naming pattern to use.  Only required/used if naming scheme is 'pattern'.-->
            <namingPattern>Parallel{c}IT</namingPattern>
            <!-- One of [SCENARIO, FEATURE]. SCENARIO generates one runner per scenario.  FEATURE generates a runner per feature. -->
            <parallelScheme>SCENARIO</parallelScheme>
            <!-- This is optional, required only if you want to specify a custom template for the generated sources (this is a relative path) -->
            <customVmTemplate>src/test/resources/cucumber-custom-runner.vm</customVmTemplate>
            </configuration>
           </execution>
         </executions>
       </plugin>
    
  2. Now add below plugin just below above plugin which will invoke runner classes generated by above plugin

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19</version>
            <configuration> 
                <forkCount>5</forkCount>
                <reuseForks>true</reuseForks>
                <includes>
                    <include>**/*IT.class</include>
                </includes>
            </configuration>
        </plugin>
    
  3. Above two plugins will do magic for cucumber test running in parallel (provided you machine also have advanced hardware support).

  4. Strictly provided <forkCount>n</forkCount> here 'n' is directly proportional to 1) Advanced Hardware support and 2) you available nodes i.e. registered browser instances to HUB.

  5. One major and most important changes is your WebDriver class must be SHARED and you should not implement driver.quit() method, as closing is take care by shutdown hook.

    import cucumber.api.Scenario;
    import cucumber.api.java.After;
    import cucumber.api.java.Before;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebDriverException;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.support.events.EventFiringWebDriver;
    
    public class SharedDriver extends EventFiringWebDriver {
        private static WebDriver REAL_DRIVER = null;
    
    
    
        private static final Thread CLOSE_THREAD = new Thread() {
            @Override
            public void run() {
                REAL_DRIVER.close();
            }
        };
    
        static {
            Runtime.getRuntime().addShutdownHook(CLOSE_THREAD);
        }
    
        public SharedDriver() {
            super(CreateDriver());
        }
    
        public static WebDriver CreateDriver() {
            WebDriver webDriver;
            if (REAL_DRIVER == null)
                webDriver = new FirefoxDriver();
            setWebDriver(webDriver);
            return webDriver;
        }
    
        public static void setWebDriver(WebDriver webDriver) {
            this.REAL_DRIVER = webDriver;
        }
    
        public static WebDriver getWebDriver() {
            return this.REAL_DRIVER;
        }
    
        @Override
        public void close() {
            if (Thread.currentThread() != CLOSE_THREAD) {
                throw new UnsupportedOperationException("You shouldn't close this WebDriver. It's shared and will close when the JVM exits.");
            }
            super.close();
        }
    
        @Before
        public void deleteAllCookies() {
            manage().deleteAllCookies();
        }
    
        @After
        public void embedScreenshot(Scenario scenario) {
            try {
                byte[] screenshot = getScreenshotAs(OutputType.BYTES);
                scenario.embed(screenshot, "image/png");
            } catch (WebDriverException somePlatformsDontSupportScreenshots) {
                System.err.println(somePlatformsDontSupportScreenshots.getMessage());
            }
        }
    }
    
  6. Considering you want to execute more than 50 threads i.e. same no of browser instances are registered to HUB but Hub will die if it doesn't get enough memory therefore to avoid this critical situation you should start hub with -DPOOL_MAX=512 (or larger) as stated in grid2 documentation.

    Really large (>50 node) Hub installations may need to increase the jetty threads by setting -DPOOL_MAX=512 (or larger) on the java command line.

    java -jar selenium-server-standalone-<version>.jar -role hub -DPOOL_MAX=512

Upvotes: 2

Anand
Anand

Reputation: 1939

Take a look at this. It might be the solution to your problem:

https://github.com/grosser/parallel_tests

Upvotes: 0

Related Questions