Parallel Test run with cucumber

放肆的年华 提交于 2019-12-22 13:11:18

问题


I am currently trying to achieve parallel test run with cucumber. I managed to run two different runners at the same time with the sure-fire plugin. Now I want to check whether is it possible to run SingleRunner file multiple times in parallel.

Ex: I have SignUpRunnerTest.java so I need to run this against few platforms parally.Is it possible?

This is my Runner file

import cucumber.api.CucumberOptions;
import cucumber.api.cli.Main;
import cucumber.api.junit.Cucumber;

import java.util.List;

import javax.management.MXBean;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Cucumber.class)
@CucumberOptions(plugin = {"pretty", "html:target/html/", "json:target/cucumber.json", "junit:TEST-all.xml"},
        features = "src/test/java/resources/features/Search.feature", glue = {"com.browserstack.stepdefs"})
public class SignUpeRunnerTest {


}

Without Runner Approach

public class SignUpeRunnerTest {

    @Test
    public void test2() {
    Main.main(new String[]{"--threads", "4","-g", "com.browserstack.stepdefs", "src/test/java/resources/features/"});
    }

}

Factory Class

`import org.openqa.selenium.WebDriver;

public final class DriverFactory {

    private static ThreadLocal<WebDriver> drivers = new ThreadLocal();

    //To quit the drivers and browsers at the end only. 
    private static List<WebDriver> storedDrivers = new ArrayList();

    static {
        Runtime.getRuntime().addShutdownHook(new Thread(){
            public void run(){
                storedDrivers.stream().forEach(WebDriver::quit);
            }
          });
    }

    private DriverFactory() {}

    public static WebDriver getDriver() {
        return drivers.get();
    }

    public static void addDriver(WebDriver driver) {
        storedDrivers.add(driver);
        drivers.set(driver);
    }

    public static void removeDriver() {
        storedDrivers.remove(drivers.get());
        drivers.remove();
    }   
}

`

Step Class

import org.openqa.selenium.By; import org.openqa.selenium.WebDriver;

public class SearchPage { private static WebDriver webDriver;

public SearchPage(WebDriver webDriver) {
    this.webDriver = webDriver;
    DriverFactory.addDriver(webDriver);
}

private By searchTermField = By.name("q");
private By submitSearch = By.id("_fZl");

public void enterSearchTerm(String searchTerm) {
    DriverFactory.getDriver().findElement(searchTermField).sendKeys(searchTerm);
}

public void submitSearch() {
    DriverFactory.getDriver().findElement(submitSearch).click();
}

}

This is my POM file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.browserstack</groupId>
    <artifactId>cucumber-jvm-java-browserstack</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>cucumber-jvm-java-browserstack</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <cucumber.jvm.parallel.version>2.2.0</cucumber.jvm.parallel.version>
        <surefire.maven.plugin.version>2.19.1</surefire.maven.plugin.version>
        <acceptance.test.parallel.count>4</acceptance.test.parallel.count>
    </properties>

    <dependencies>

        <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>

        <!-- https://mvnrepository.com/artifact/com.gfk.senbot/senbot-maven-plugin -->

  <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.0.1</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M3</version>
                <configuration>
                    <parallel>methods</parallel>
                    <threadCount>4</threadCount>
                    <reuserForks>false</reuserForks>
                    <testErrorIgnore>true</testErrorIgnore>
                    <testFailureIgnore>true</testFailureIgnore>
                    <includes>
                        <include>**/*RunnerTest.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

回答1:


info.cukes dependency (are pretty old) which support cucumber till v 1.2.5 only and No more support for this after 12 September 2016

Other side, io.cucumber dependency supports Cucumber starting from v 2.0.x till latest v 4.3.x available as of now (Cucumber-JVM 4.0 gives you much flexibility for implementing parallel execution) and below are the steps to implement parallel execution using io.cucumber (Here you do not need to create individual runners per feature file & No need to use any old plug in like jvm-parallel plug in)

1.Adding correct set of dependency. I have followed JUnit during the implementation.

<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-picocontainer</artifactId>
    <version>4.2.3</version>
    <scope>test</scope>
</dependency>

2.Adding Maven-Surefire-Plugin under POM.XML

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M3</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>



回答2:


Cucumber feature files can be executed without using any runner by using the main() method in class Main of package cucumber.api.cli. Refer to this cli usage and this article. Using this maybe it will work. Need some changes though.

  1. Copy the code of BrowserStackJUnitTest into a new class rename it to something else say NewBSTest. This class will be used for running the test.

  2. Some change will be required in how the driver created for each thread will be accessed by selenium and cucumber code.

  3. Need to use a factory to store the drivers in a ThreadLocal variable in NewBSTest. U can refer to this class.

  4. In the NewBSTest class that u have created remove line no 30 - public WebDriver driver;. Change line 94 to add the created RemoteWebDriver to the ThreadLocal variable. SOmething like DriverFactory.addDriver(driver). Add DriverFactory.removeDriver() in method tearDown() line 98, maybe the first line. Change existing driver.quit(); to DriverFactory.getDriver().quit().

5.Remove the shutdown hook in the DriverFactory, BrowserStack will be quitting the actual driver anyways.

  1. Now in selenium or cucumber code u can access the driver using DriverFactory.getDriver(). This will impact your existing code pretty heavily.

  2. In the NewBSTest class add a test method like this. Hopefully this will work and the same features will be executed in each of the configured browserstack environments.

@Test
public void test() {
Main.main(new String[]{""-g", "stepdef", "src/test/resources/features/"});
}


来源:https://stackoverflow.com/questions/55760140/parallel-test-run-with-cucumber

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!