简体   繁体   English

使用Failsafe + Cucumber Parallel插件时无法使用@BeforeClass @AfterClass等Junit或TestNG注释

[英]Not able to use Junit or TestNG Annotations like @BeforeClass @AfterClass while using Failsafe + Cucumber Parallel plugin

I am trying to do Parallel testing using Selenium and Cucumber.So we have around 130 test scenarios which takes around 1.5 hours to run. 我正在尝试使用Selenium和Cucumber进行并行测试。所以我们有大约130个测试场景,大约需要1.5小时才能运行。 Now By running all these tests in Parallel I can reduce the time. 现在通过并行运行所有这些测试,我可以减少时间。

I am using following 2 plugins: 我正在使用以下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>

So the idea is, suppose I give Thread count or Fork count 3, it will invoke 3 browsers, and it will run the tests. 所以我的想法是,假设我给出了Thread count或Fork count 3,它将调用3个浏览器,它将运行测试。 With CUcumber JVM Parallel Plug in I have created 131 runner for all the scenarios. 使用CUcumber JVM Parallel Plug in我为所有场景创建了131个跑步者。 With @Before annotation from Cucumber, I can invoke the browser once, and for all the next instances it will use the same browser instance (Thus saving the time to open and close the browsers again and again.) 使用Cucumber的@Before注释,我可以调用一次浏览器,对于所有下一个实例,它将使用相同的浏览器实例(这样可以节省一次又一次打开和关闭浏览器的时间。)

Now if we can use @BeforeClass or @AfterClass, this would have been much simpler solution. 现在,如果我们可以使用@BeforeClass或@AfterClass,这将是一个更简单的解决方案。 But as we can not. 但是我们做不到。 I had to use @Before, thus calling the same method again and again with each scenario. 我不得不使用@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();
           }}

So this worked for @Before, but this will not work for @After. 所以这适用于@Before,但这不适用于@After。 What I want to achieve here is to close all the browser instances after the test is done. 我想在这里实现的是在测试完成后关闭所有浏览器实例。 But How do I know which 1 is the final instance? 但我如何知道哪一个是最终实例? Or how do I close all the instances? 或者如何关闭所有实例? Is there a way to use @AfterClass or @BeforeCLass or use SetupTeardown with JUnit/TestNG + Maven-Failsafe-plugin? 有没有办法使用@AfterClass或@BeforeCLass或使用SetupTeardown和JUnit / TestNG + Maven-Failsafe-plugin?

I have tried using Junit and TestNG both. 我尝试过使用Junit和TestNG。 I used to use a Runner file which extends to the SetupTearDown class for the non-parallel execution. 我曾经使用Runner文件扩展到SetupTearDown类以进行非并行执行。 But obviously can not use that as the runner classes are getting generated in runtime. 但显然无法使用它,因为运行时会生成运行器类。 Tried using pre-integration , post-integration phase as well. 尝试使用预集成,后集成阶段。 Which did not run. 哪个没跑。 May be I am not using that phase correctly. 可能是我没有正确使用那个阶段。

Lets move step by step. 让我们一步一步走。 First we shall use Cucumber V starting from 4.0 onward as it supports parallel execution and we shall add below dependencies in order to implement it. 首先,我们将从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>  

Then we shall start using maven-surefire plugin in order to actually run tests in parallel using parallel & threadCount properties as mentioned below - 然后我们将开始使用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>

Depending on implementation, it would run test cases in different browser & close all. 根据实现,它将在不同的浏览器中运行测试用例并关闭所有。 Now if you want to do something specific only once before or after the execution, you shall use @BeforeClass or @AfterClass in RunCuke Java file. 现在,如果您只想在执行之前或之后执行一次特定操作,则应在RunCuke Java文件中使用@BeforeClass或@AfterClass。 Things are Thread Safe. 事情是线程安全的。

Looking into your existing code it's not thread safe and will not allow you parallel execution because of static Browser . 查看现有代码,它不是线程安全的,并且由于静态Browser而不允许并行执行。 You should try using QAF - Pure TestNG implementation for BDD/Gherkin Which provides gherkin implementation that allows you to use all TestNG listener as well as have additional listeners for driver and element. 您应该尝试使用QAF - 用于BDD / Gherkin的Pure TestNG实现,它提供了小黄瓜实现 ,允许您使用所有TestNG侦听器以及为驱动程序和元素提供额外的侦听器。 Furthermore driver management taken care by qaf so you may not need to write additional code to manage driver or other test automation specific needs. 此外,qaf负责驱动程序管理,因此您可能不需要编写其他代码来管理驱动程序或其他测试自动化特定需求。 qaf will take care of close all the browser instances after the test and will also allow you scenario level parallel execution. qaf将在测试后关闭所有浏览器实例,并允许您进行场景级并行执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM