Внедрение зависимости для инициализации драйвера в проекте огурца и использования хука без завершения сеанса - PullRequest
1 голос
/ 06 ноября 2019

Я пытаюсь реализовать огурец с помощью Page Object Model, и у меня возникла пара проблем, и у меня возникло много вопросов.

  1. Мое приложение для iOS не настолько сложное, но я все еще хочуorginize все stepdefs и функции, чтобы соответствовать страницам из POM. Так что у меня будет несколько пасынков и бегунов. Как лучше всего организовать все это? Я попробовал Pico DI, но даже не смог пропустить через него мой экземпляр драйвера (если вы можете, пожалуйста, предоставьте структурное решение)

  2. Так как s native iOS - I m не собираетсязакройте приложение после каждого сценария (это займет вечность). Но я все еще хочу сохранить функции СУХОЙ для повторного использования. Как лучше всего создать один экземпляр драйвера appium и никогда не создавать другой, пока функция не будет выполнена? Я понимаю, что мне просто нужно добавить driver.quit на последнем шаге. С чем я сталкиваюсь, так это с использованием одного и того же драйвера во всем проекте (Pages, Stepdefs) (см. Код)

  3. Я собираюсь запустить тесты с TestNg и спросить, аннотации @Before @Afterвсе еще работают в отчимах или их лучше избегать?

  4. ОСНОВНОЙ вопрос: Внедрение зависимостей с пико. Поскольку все мои тесты являются приемочными (сквозные функциональные тесты), мне интересно, будет ли хорошей идеей создать один класс InjectionSetUp, который будет содержать все мои страницы И драйвер

Диспетчер драйверов

public class IOSDriverManager {
    public static ThreadLocal<IOSDriver<IOSElement>> webDriver = new ThreadLocal<IOSDriver<IOSElement>>();

 public static DesiredCapabilities getIOSCapsLocal() {
        DesiredCapabilities caps = new DesiredCapabilities();
         //My caps
  return caps;

 public static void createThreadLocalWebDriver() {
        IOSDriver<IOSElement> driver = null;
//try catch
      driver = new IOSDriver<IOSElement>(new URL(APPIUM_SERVER_URL), getIOSCapsLocal());
//try catch
        webDriver.set(driver);
 }
 public static IOSDriver<IOSElement> getThreadLocalDriver() {
        IOSDriver<IOSElement> driver = webDriver.get();
        if (driver == null) {
            createThreadLocalWebDriver();
            driver = webDriver.get();
        }
        return driver;
    }

BasePage

public class BasePage {
    IOSDriver<IOSElement> Driver;
    public BasePage(IOSDriver<IOSElement> driver) {
     initElements();
     Driver = driver;
    }

    private void initElements() {

        PageFactory.initElements(new AppiumFieldDecorator(getDriver()),this);
    }

    protected IOSDriver<IOSElement> getDriver() {
        return IOSDriverManager.getThreadLocalDriver();
    }

}

AnyPage

public class BiosurveyPage extends BasePage {
 public BiosurveyPage(IOSDriver<IOSElement> driver) {
        super(driver); //  Appiumfield  decorator is applied by BasePage constructor
//Is it better to just use getDriver() method throughout all pages instead of declaring driver again ? 
    }

Окончательно StepDefs

public class newSignUpFlowTest{
    protected IOSDriver<IOSElement> getDriver() {
        return IOSDriverManager.getThreadLocalDriver();
    }
    LoginPage poLogin = new LoginPage(getDriver());
    SignUpPage poSignup = new SignUpPage(getDriver());
      // 10+ pages 

@Given("I am on Login Page")
    public void iAmOnLoginPage() {
        assertThat("ON LOGIN PAGE",poLogin.isLoginScreen(),equalTo(true));
    }

    @When("I tap on Sign Up Link")
    public void iTapsOnSignUpLink() {
        poLogin.clickSignUp();
    }
// 20+ methods for this feature

ОБНОВЛЕНИЕ Я все исправил и смог запустить тесты. Теперь мой вопрос - мой каркас выглядит прилично? Я t have any real life experience prior to this. So can someone just approve me and suggest enhancements to keep up with best industry practices ? I know this post might piss some people off, but i don не знаю, где еще сообщить об этом, так как у меня нет друзей в области обеспечения качества и удаленной работы

1 Ответ

1 голос
/ 07 ноября 2019

При использовании внедрения зависимостей вы хотите, чтобы ваша система DI выполняла всю тяжелую работу. Таким образом, у ваших определений шагов есть зависимость конструктора от объектов вашей страницы.

public class NewSignUpFlowStepDefinitions {

    private final LoginPage poLogin;
    private final SignUpPage poSignup;

    NewSignUpFlowStepDefinitions(LoginPage poLogin, SignUpPage poSignup) {
        this.poLogin = poLogin;
        this.poSignup = poSignup;
    }

    @Given("I am on Login Page")
    public void iAmOnLoginPage() {
        assertThat("ON LOGIN PAGE", poLogin.isLoginScreen(), equalTo(true));
    }

    @When("I tap on Sign Up Link")
    public void iTapsOnSignUpLink() {
        poLogin.clickSignUp();
    }

}

У ваших страниц не может быть зависимости конструктора от IOSDriver<IOSElement>, потому что PicoContainer может создавать только цепочки зависимостей, которые не заканчиваются пустымиконструкторы. Поэтому вместо этого мы используем IOSDriverManager здесь.

public class BiosurveyPage extends BasePage {
    public BiosurveyPage(IOSDriverManager driverManager) {
        super(driverManager);
    }
}

В вашем BasePage вы затем распаковываете веб-драйвер из диспетчера драйверов.

public abstract class BasePage {
    private IOSDriverManager driverManager;

    public BasePage(IOSDriverManager driverManager) {
        this.driverManager = driverManager;
        initElements();
    }

    private void initElements() {
        PageFactory.initElements(new AppiumFieldDecorator(driverManager.getDriver()), this);
    }

    protected IOSDriver<IOSElement> getDriver() {
        return driverManager.getDriver();

    }
}

Затем в IOSDriverManager выможет сохранить ссылку на веб-драйвер и создать его по мере необходимости. Если вы уверены, что ваш веб-драйвер безопасен для совместного использования между сценариями, вы все равно можете использовать ThreadLocal здесь.

public class IOSDriverManager implements Disposable{
    private IOSDriver<IOSElement> webDriver;

    private DesiredCapabilities getIOSCapsLocal() {
        DesiredCapabilities caps = new DesiredCapabilities();
        return caps;
    }

    private void createWebDriver() {
        webDriver = new IOSDriver<IOSElement>(new URL(APPIUM_SERVER_URL), getIOSCapsLocal());
    }

    public IOSDriver<IOSElement> getDriver() {
        if (webDriver == null) {
            createThreadLocalWebDriver();
        }
        return webDriver;
    }

    @Override
    public void dispose() {
        // Stop webdriver ehre
    }
}

Обратите внимание, что Disposable добавляет метод dispose, который позволит вам очистить драйверпосле каждого сценария. Либо полностью утилизировать, либо вернуть в известное состояние.

http://picocontainer.com/lifecycle.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...