【问题标题】:Not able to use Junit or TestNG Annotations like @BeforeClass @AfterClass while using Failsafe + Cucumber Parallel plugin在使用 Failsafe + Cucumber Parallel 插件时无法使用诸如 @BeforeClass @AfterClass 之类的 Junit 或 TestNG 注释
【发布时间】:2019-04-04 18:23:06
【问题描述】:

我正在尝试使用 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>

所以想法是,假设我给线程数或叉数 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。我在这里要实现的是在测试完成后关闭所有浏览器实例。但是我怎么知道哪个 1 是最后一个实例?或者我如何关闭所有实例?有没有办法使用 @AfterClass 或 @BeforeCLass 或将 SetupTeardown 与 JUnit/TestNG + Maven-Failsafe-plugin 一起使用?

我尝试过同时使用 Junit 和 TestNG。我曾经使用扩展至 SetupTearDown 类的 Runner 文件来进行非并行执行。但显然不能使用它,因为运行时会生成运行器类。也尝试使用 pre-integration , post-integration 阶段。哪个没有运行。可能是我没有正确使用那个阶段。

【问题讨论】:

  • 如果你使用的黄瓜版本大于 4,那么你应该使用内置的并行执行支持,无论是 junit 还是 testng。 cucumber.io/blog/announcing-cucumber-jvm-4-0-0。它更干净,更简单。关于驱动程序重用,您可以将驱动程序存储在静态 ThreadLocal 变量中。这可能会有所帮助。 -stackoverflow.com/questions/55266736/…。事实上cucumber-jvm-parallel-plugin的插件创建者建议停止使用插件github.com/temyers/cucumber-jvm-parallel-plugin
  • 好吧,现在更新黄瓜文件不是一个选项,因为我们的项目需要很多更改,即使这样,我也尝试过使用 Cucumber 4。我尝试使用链接中提到的步骤已经为 Cucumber 4 提供了,但它根本没有创建多个浏览器实例。 :( 我会再试一次,TestNg 可能可行。但这有点棘手,因为我需要在这个项目中进行很多更改以使其与 Cucumber 4 兼容。
  • 不过,感谢您的回复。 :)
  • 所以我尝试使用 TestNg 和 CUcumber 4.2.6,但它继续并行运行所有测试,但在同一个浏览器中。不确定如何对浏览器实例进行线程安全。有没有更简单的方法来做到这一点?

标签: java maven junit cucumber testng


【解决方案1】:

让我们一步一步来。首先,我们将从 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 插件,以便使用下面提到的并行和 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。事情是线程安全的。

【讨论】:

  • 感谢@TheSociety 的详尽回答。但问题是,Surefire 无法识别 BeforeClass 或 AfterClass,因此它不会运行它。它只运行 Cucumber 相关方法/注释。就像之前和之后一样。这对在测试开始和结束时调用浏览器没有帮助。
  • 请理解 @BeforeClass 是由 JUnit/testNG 使用 import org.junit.BeforeClass 调用的,我已经运行了很长时间。请不要将这些方法与 surefire 相关联。 Surefire 与这些注释无关。
  • 是的,@TheSociety 这就是问题所在。你能告诉我你是如何使用surefire插件运行Junit测试的吗?我一直在尝试这样做。我的意思是你是如何执行它的?来自命令行 maven 还是来自 IntelliJ 之类的 IDE?
【解决方案2】:

查看您现有的代码,它不是线程安全的,并且由于静态Browser 而不允许您并行执行。 您应该尝试使用QAF - Pure TestNG implementation for BDD/Gherkin,它提供了gherkin implementation,允许您使用所有TestNG 侦听器,并为驱动程序和元素提供额外的listeners。此外,驱动程序管理由 qaf 负责,因此您可能不需要编写额外的代码来管理驱动程序或其他测试自动化特定需求。 qaf 将在测试后关闭所有浏览器实例,并允许您在场景级别并行执行。

【讨论】:

    猜你喜欢
    • 2010-12-27
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多