我在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
有人可以帮助我实现这一点吗?我使用的是cumul-java 1.2.2版本,并且使用AbstractTestNGCucumberTests作为运行程序。另外,让我知道如何使用功能文件动态创建Test Runner,并使它们并行运行。
<dependency> <groupId>com.github.temyers</groupId> <artifactId>cucumber-jvm-parallel-plugin</artifactId> <version>2.1.0</version> </dependency>
首先,你需要在项目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>
现在在上方插件下方添加下方插件,它将调用由上方插件生成的运行器类
<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>
上面的两个插件可以并行运行黄瓜测试(只要你的机器还具有高级硬件支持)。
<forkCount>n</forkCount>此处严格提供的 “ n”与1)高级硬件支持和2)可用节点(即注册到HUB的浏览器实例)成正比。
<forkCount>n</forkCount>
一个主要的和最重要的变化是你的webdriver类必须是SHARED,你应该不执行driver.quit()方法,如封闭是照管关闭挂钩。
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()); } } }
考虑到你要执行50个以上的线程,即没有向HUB注册相同的浏览器实例,但是如果Hub没有足够的内存,它将死掉,因此,为避免这种严重情况,你应该使用-DPOOL_MAX = 512(或更大)来启动Hub如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