How to execute a parallel cucumber description file

I have below function files (Separate function files) in src / test / resources / feature / and I would like to run them in parallel. For example: one function file should be executed in chrome, and another should be executed in firefox, as the @Tags name is indicated.

Feature: Refund item @chrome Scenario: Jeff returns a faulty microwave Given Jeff has bought a microwave for $100 And he has a receipt When he returns the microwave Then Jeff should be refunded $100 Feature: Refund Money @firefox Scenario: Jeff returns the money Given Jeff has bought a microwave for $100 And he has a receipt When he returns the microwave Then Jeff should be refunded $100 

Can anyone help me achieve this. I am using cucumber-java version 1.2.2 and AbstractTestNGCucumberTests, using as a runner. Also let me know how I can dynamically create a test runner using function files and running them in parallel.

+3
source share
3 answers

Update: Version 4.0.0 is available in the maven central repository with many changes. See here for more details.

Update: Version 2.2.0 is available in the maven central repository.

You can use the opensource cucumber-jvm-parallel-plugin plugin , which has many advantages over existing solutions. Available at maven repository

  <dependency> <groupId>com.github.temyers</groupId> <artifactId>cucumber-jvm-parallel-plugin</artifactId> <version>2.1.0</version> </dependency> 
  • First you need to add this plugin with the necessary configuration to the pom project file.

     <plugin> <groupId>com.github.temyers</groupId> <artifactId>cucumber-jvm-parallel-plugin</artifactId> <version>2.1.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> 
  • Now add below the plugin just below the plugin that will call the runner classes created by the 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> 
  • The above two plugins will do the magic for checking the cucumber running in parallel (provided that you also have advanced hardware support).

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

  • One of the main and most important changes is your WebDriver SHARED class, and you should not implement the driver.quit () method, since closing is the job of shutting down.

     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 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()); } } } 
  • Given that you want to execute more than 50 threads, i.e. the same number of browser instances is not registered in the HUB, but the Hub will die if it does not receive enough memory, so to avoid this critical situation, you must start the hub with -DPOOL_MAX = 512 (or more), as indicated in the 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

+7
source

Cucumbers do not support parallel execution out of the box. I tried, but it is not friendly.

  • We must use the maven function to call it in parallel. Refer link
  • There is also a github project that uses a custom plugin for parallel execution. See cucumber-jvm-parallel-plugin
+4
source

If all you expect is the ability to run multiple functions in parallel, you can try the following:

  • Duplicate the AbstractTestNGCucumberTests class in the test project and set the parallel=true attribute to the annotated @DataProvider method.

Since the default dataprovider-thread-count from TestNG is 10 , and now that you have instructed TestNG to run features in parallel, you should start looking at your function files that will be executed in parallel.

But I understand that Cucumber messages are essentially not thread safe, so your reports may look garbled.

+1
source

Source: https://habr.com/ru/post/1238986/


All Articles