如何并行执行黄瓜功能文件

新手上路,请多包涵

我在 src/test/resources/feature/ 中有以下功能文件(单独的功能文件),我想并行运行它们。比如:一个功能文件必须在 chrome 中执行,另一个功能文件必须在 firefox 中执行,如@Tags 名称所述。

 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

有人可以帮助我实现这一点。我正在使用 cucumber-java 1.2.2 版本,并将 AbstractTestNGCucumberTests 用作跑步者。另外,让我知道如何使用功能文件动态创建测试运行程序并使它们并行运行。

原文由 ArrchanaMohan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 461
2 个回答

更新: 4.0.0 版本可在 maven 中央存储库中获得,其中包含大量更改。 有关更多详细信息,请访问此处。

更新: 2.2.0 版本可在 Maven 中央存储库中获得。

您可以使用开源插件 cucumber-jvm-parallel-plugin ,它比现有解决方案有很多优势。可在 maven 存储库 中获得

   <dependency>
     <groupId>com.github.temyers</groupId>
     <artifactId>cucumber-jvm-parallel-plugin</artifactId>
     <version>2.1.0</version>
   </dependency>

  1. 首先,您需要在项目 pom 文件中添加具有所需配置的此插件。
    <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>

  1. 现在在插件正下方添加下面的插件,它将调用上面插件生成的运行器类
       <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>

  1. 以上两个插件将为并行运行的黄瓜测试带来魔力(前提是您的机器还具有高级硬件支持)。

  2. 严格提供 <forkCount>n</forkCount> 这里的“n”与 1) 高级硬件支持和 2) 可用节点(即向 HUB 注册的浏览器实例)成正比。

  3. 一项主要且最重要的更改是您的 WebDriver 类必须是 SHARED 并且您 应该实现 driver.quit() 方法,因为关闭是由 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());
           }
       }
   }

  1. 考虑到你想执行超过 50 个线程,即相同数量的浏览器实例注册到集线器,但如果集线器没有足够的内存,集线器将会死亡,因此为了避免这种危急情况,你应该使用 -DPOOL_MAX=512(或更大)启动集线器如 grid2 文档 中所述。

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

原文由 Sugat Mankar 发布,翻译遵循 CC BY-SA 3.0 许可协议

Cucumber 不支持开箱即用的并行执行。我已经尝试过了,但它并不友好。

  1. 我们必须使用 maven 的能力来并行调用它。参考 链接
  2. 还有一个 github 项目使用自定义插件并行执行。参考 cucumber-jvm-parallel-plugin

原文由 Bharath 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题