我正在尝试使用Selenium和Cucumber进行并行测试。所以我们有大约130个测试场景,大约需要1.5小时才能运行。现在通过并行运行所有这些测试,我可以减少时间。
我正在使用以下2个插件:
<plugin>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<version>5.0.0</version>
<executions>
<execution>
<id>generateRunners</id>
<phase>generate-test-sources</phase>
<goals>
<goal>generateRunners</goal>
</goals>
<configuration>
<outputDirectory>runner</outputDirectory>
<glue>
<package>${PackageName}</package>
</glue>
<featuresDirectory>${FeaturesDirectory}</featuresDirectory>
<cucumberOutputDir>target/cucumber-parallel</cucumberOutputDir>
<format>json</format>
<plugins>
<plugin>
<name>json</name>
</plugin>
</plugins>
<useTestNG>true</useTestNG>
<parallelScheme>SCENARIO</parallelScheme>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>acceptance-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
<includes>
<include>**/Parallel*IT.class</include>
</includes>
<properties>
<property>
<name>junit</name>
<value>false</value>
</property>
</properties>
</configuration>
</execution>
</executions>
</plugin>
所以我的想法是,假设我给出了Thread count或Fork count 3,它将调用3个浏览器,它将运行测试。使用CUcumber JVM Parallel Plug in我为所有场景创建了131个跑步者。使用Cucumber的@Before注释,我可以调用一次浏览器,对于所有下一个实例,它将使用相同的浏览器实例(这样可以节省一次又一次打开和关闭浏览器的时间。)
现在,如果我们可以使用@BeforeClass或@AfterClass,这将是一个更简单的解决方案。但是我们做不到。我不得不使用@Before,因此每个场景一次又一次地调用相同的方法。
import cucumber.api.java.Before;
public class stepdefs(){
static Browser browser;
public static Scenario scenario;
static TestConfiguration configuration = TestConfiguration.getConfiguration();
@Before
public void before(Scenario scenario) {
if (browser == null) {
if (System.getProperty("seleniumRemoteWebDriver") == null) {
WebTestSettings webTestSettings = configuration.getWebTestSettings();
browser = Browser.LOAD_LOCAL_BROWSER(webTestSettings.externalBrowser, webTestSettings.driverPath);
} else {
if (System.getProperty("version") == null) {
browser = new RemoteBrowser(System.getProperty("browser"), System.getProperty("seleniumRemoteWebDriver"), System.getProperty("platform"));
} else {
browser = new RemoteBrowser(System.getProperty("browser"), System.getProperty("seleniumRemoteWebDriver"), System.getProperty("platform"), System.getProperty("version"));
}
}
TestContext.getContext().setBrowser(browser);
}
Browser browser = TestContext.getContext().getBrowser();
this.scenario = scenario;
browser.driver.manage().window().maximize();
}}
所以这适用于@Before,但这不适用于@After。我想在这里实现的是在测试完成后关闭所有浏览器实例。但我如何知道哪一个是最终实例?或者如何关闭所有实例?有没有办法使用@AfterClass或@BeforeCLass或使用SetupTeardown和JUnit / TestNG + Maven-Failsafe-plugin?
我尝试过使用Junit和TestNG。我曾经使用Runner文件扩展到SetupTearDown类以进行非并行执行。但显然无法使用它,因为运行时会生成运行器类。尝试使用预集成,后集成阶段。哪个没跑。可能是我没有正确使用那个阶段。
让我们一步一步走。首先,我们将从4.0开始使用Cucumber V,因为它支持并行执行,我们将添加以下依赖项以实现它。
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.2.3</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>datatable</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>4.2.3</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.2.3</version>
<scope>test</scope>
</dependency>
然后我们将开始使用maven-surefire插件,以便使用parallel&threadCount属性实际并行运行测试,如下所述 -
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire.plugin.version}</version>
<configuration>
<parallel>methods</parallel>
<threadCount>1</threadCount>
<reuserForks>false</reuserForks>
<testErrorIgnore>true</testErrorIgnore>
<testFailureIgnore>true</testFailureIgnore>
<includes>
<include>**/*RunCukeTest.java</include>
</includes>
</configuration>
</plugin>
根据实现,它将在不同的浏览器中运行测试用例并关闭所有。现在,如果您只想在执行之前或之后执行一次特定操作,则应在RunCuke Java文件中使用@BeforeClass或@AfterClass。事情是线程安全的。
查看现有代码,它不是线程安全的,并且由于静态Browser
而不允许并行执行。您应该尝试使用QAF - Pure TestNG implementation for BDD/Gherkin提供gherkin implementation,它允许您使用所有TestNG监听器以及为驱动程序和元素添加额外的listeners。此外,qaf负责驱动程序管理,因此您可能不需要编写其他代码来管理驱动程序或其他测试自动化特定需求。 qaf将在测试后关闭所有浏览器实例,并允许您进行场景级并行执行。