Cucumber-Appium - 如果在 @Before 中初始化驱动程序,则将 Hook 存储在何处 [英] Cucumber-Appium - Where to store Hooks if initialising driver in @Before

查看:21
本文介绍了Cucumber-Appium - 如果在 @Before 中初始化驱动程序,则将 Hook 存储在何处的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将尝试解释我是如何构建它的,我想可能会有一些明显的东西跳出来.

I'll try to explain how I've built this, I imagine something obvious may jump out.

我对此比较陌生,但正在构建一个黄瓜应用程序框架并且遇到了一些麻烦.目前,我在我的 @Before 钩子中初始化我的 Appium 驱动程序,该钩子位于包含所有钩子的 GlobalHooks 类中.我已经改变了钩子,所以它的一部分只在测试运行开始时运行,因为 Cucumber 不支持全局钩子,我不明白为什么我应该在每次测试之前初始化驱动程序(我使用的是 Junit,所以不能TestNG 的@BeforeSuite 功能的优势).

I'm relatively new to this but am building a cucumber-appium framework and am running into some trouble. Currently, I initialise my Appium driver in my @Before hook which is in a GlobalHooks class which contains all Hooks. I have altered the hook so part of it only runs at the start of the test run as Cucumber doesn't support global hooks and I don't see why I should initialise the driver before every test (I'm using Junit so cannot take advantage of TestNG's @BeforeSuite feature).

为了利用 Appium 的并行会话,我现在想让我的驱动程序(在 GlobalHooks 类中声明并在该类的 @Before 方法中定义)非静态,并且它会在整个套件中呈现问题.

To take advantage of Appium's parallel sessions, I now want to make my driver (declared in a GlobalHooks class and defined in the @Before method in that class) non-static and it's presenting issues across the suite.

如果我希望我的页面类使用这个驱动程序,在这样的 Hook 中定义我的驱动程序是否明智?或者有人对如何初始化非静态驱动程序有任何建议,以便它们可以用于运行并行 Appium 会话?

Is it wise to define my driver in a Hook like this if I want my Page Classes to use this driver? Or does anyone have any advice on how to initialise non-static drivers so they can be used to run parallel Appium sessions?

这可能更像是一个 Java 问题,而不是关于 Cucumber 或 Appium 的问题.

This is probably more of a Java question than about Cucumber or Appium.

推荐答案

这是并行使用 selenium 驱动程序的精简版本.采用appium驱动应该类似.这使用 pico-container 在场景中创建和共享对象.需要添加cucumber-picocontainer依赖.

This is a stripped down version of using selenium drivers in parallel. It should be similar to adopt to appium driver. This uses pico-container for object creation and sharing across a scenario. Need to add cucumber-picocontainer dependency.

DriverFactory 将所有驱动程序存储在 ThreadLocal 变量 drivers 中.

DriverFactory stores all the drivers in a ThreadLocal variable drivers.

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();
    }   
}

<小时>

存在仅用于允许 pico-container 创建所需的驱动程序.检查驱动程序是否已存在以供线程重用.为了避免这种情况,您可以查看扩展 ThreadLocal 类并设置 initialValue() 方法.

public class SharedDriver {
    public SharedDriver() {
        if (DriverFactory.getDriver() == null) {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver.exe");
        DriverFactory.addDriver(new ChromeDriver());
    }
    }   
}

<小时>

public class GoogleHomePO extends LoadableComponent<GoogleHomePO>{

    @FindBy(name="q")
    private WebElement searchTextBox;

    public GoogleHomePO() {
        DriverFactory.getDriver().get("https://www.google.com/");
        PageFactory.initElements(DriverFactory.getDriver(), this);
    }

    public void enterSearch(String search) {
        searchTextBox.sendKeys(search);
    }
}

<小时>

SharedDriver 类需要添加到项目中的任何一个步骤定义构造函数中.当 Cucumber 为每个场景初始化所有 step 和 hook 类时,picocontainer 将在需要时实例化驱动程序对象并将其存储在 DriverFactory 中.


The SharedDriver class needs to be added to any one step definition constructor in the project. As cucumber initializes all the step and hook classes for each scenario picocontainer will instantiate the driver object if required and store it in the DriverFactory.

public class StepDefinition {

    private GoogleHomePO gmPO;

    public StepDefinition(SharedDriver driver, GoogleHomePO gmPO) {
        this.gmPO = gmPO;
    }

    @Given("Go to google page")
    public void given() {
        gmPO.get();
    }

    @When("Enter search {string}")
    public void when(String search) {
        gmPO.enterSearch(search);
    }    
}

<小时>

功能文件 1


Feature file 1

Feature: 

  Scenario: First
    Given Go to google page
    When Enter search "From Feature One"

  Scenario: First Again
    Given Go to google page
    When Enter search "From Feature One Again Again"

<小时>

功能文件 2


Feature file 2

Feature:

  Scenario: Second
    Given Go to google page
    When Enter search "From Feature Two"

<小时>

POM 设置


POM settings

<plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                        <configuration>
                            <includes>
                                <include>**/*Runner.java</include>
                            </includes>

                            <parallel>methods</parallel>
                            <useUnlimitedThreads>true</useUnlimitedThreads>

                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>

这篇关于Cucumber-Appium - 如果在 @Before 中初始化驱动程序,则将 Hook 存储在何处的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆