Cucumber-Appium - где хранить хуки при инициализации драйвера в @Before - PullRequest
1 голос
/ 20 марта 2019

Я попытаюсь объяснить, как я это построил, я думаю, что может появиться что-то очевидное.

Я относительно новичок в этом, но я строю фреймворк с огуречным аппием и столкнулся с некоторыми проблемами. В настоящее время я инициализирую свой драйвер Appium в своем хуке @Before, который находится в классе GlobalHooks, который содержит все хуки. Я изменил хук, поэтому его часть запускается только в начале теста, поскольку Cucumber не поддерживает глобальные хуки, и я не понимаю, почему я должен инициализировать драйвер перед каждым тестом (я использую Junit, поэтому не могу взять Преимущество функции TestNG @BeforeSuite).

Чтобы воспользоваться преимуществами параллельных сессий Appium, теперь я хочу, чтобы мой драйвер (объявленный в классе GlobalHooks и определенный в методе @Before в этом классе) не был статичным, и это вызывает проблемы во всем комплекте.

Разумно ли определять мой драйвер в Hook, как этот, если я хочу, чтобы мои классы страниц использовали этот драйвер? Или у кого-нибудь есть советы по инициализации нестатических драйверов, чтобы их можно было использовать для параллельных сеансов Appium?

Вероятно, это скорее вопрос Java, чем вопрос о Cucumber или Appium.

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Это урезанная версия параллельного использования драйверов селена. Это должно быть похоже на принятие к драйверу appium. Это использует пико-контейнер для создания объекта и совместного использования в сценарии. Необходимо добавить зависимость cucumber-picocontainer.

DriverFactory сохраняет все драйверы в переменной ThreadLocal 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();
    }   
}

Существует исключительно для разрешения пико-контейнера для создания требуемого драйвера. Проверяет, существует ли уже драйвер для повторного использования потока. Чтобы избежать этого, вы можете взглянуть на расширение класса 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.

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: 

  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:

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

Настройки POM

<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>
0 голосов
/ 14 мая 2019

@ кузнечик. Возвращаюсь к вам, потому что я сказал, что буду, когда у меня будет что-то, что соответствует моим настройкам. Еще раз спасибо за ваш вклад, это было неоценимо. Я установил класс SharedDriver, как вы предложили, но изменил одну или две вещи, чтобы учесть, что я буду запускать каждый поток на другом подключенном устройстве, то есть каждый раз использовать отдельный AppiumDriver вместо нового WebDriver.

Я решил эту проблему, добавив в свой метод BeforeClass класс для создания пула всех подключенных устройств. Затем мой SharedDriver выполняет итерацию по ним, используя AtomicIntecger, чтобы сохранить многопоточность, и добавляет соответствующий драйвер на завод.

Мне также понравилась идея запуска тестов из IDE на первом подключенном устройстве для отладки и быстрых тестов. Поскольку BeforeClass не запускается при запуске из среды IDE, мой класс SharedDriver проверяет это, и если он не запускается, он добавляет один AppiumDriver для первого подключенного устройства и вместо этого запускает на нем тест.

Извините за задержку с возвращением, с тех пор я работаю над другими вещами. И еще раз спасибо за вашу помощь

...