Объектная модель страницы.Композиция против инкапсуляции - PullRequest
1 голос
/ 16 мая 2019

У нас есть сложное многостраничное приложение, содержащее до 100 веб-элементов на одной странице, несколько сеток, динамических элементов и т. Д. Шаблон POM требует, чтобы все, что касается страницы, было инкапсулировано в страницу, т.е. в страницу.класс, мне нужно определить мои локаторы как строки или Bys.Я также должен определить публичные методы взаимодействия с этими элементами.Существует два способа обработки этих взаимодействий:

  1. Определить метод для каждого элемента и каждого взаимодействия.Например, у меня есть элемент «Отправить».В своем классе страниц я бы создал открытый метод ClickSubmit (), а в своем тесте я бы вызвал его.Submit будет содержать Driver.FindElement (submitLocator) .Click ();Если бы у меня было много элементов на странице, у меня было бы столько же методов, по сути повторяющих одну и ту же функцию.
  2. Определите метод однократного щелчка, который принимает локатор веб-элементов в качестве параметра и, используя сложный оператор switch, определяеткакой элемент следует щелкнуть.

Оба метода работают для небольших страниц с ограниченным числом элементов.

Однако существует третий способ определения общего метода щелчка в вспомогательном классе.в BasePage (все страницы наследуются от BasePage) или определяют методы расширения, которые будут действовать непосредственно на элемент.Вспомогательные методы могут иметь дополнительное преимущество встроенных ожиданий.

В любом случае, методы взаимодействия будут определены только один раз, и составителю тестов не нужно будет знать, как щелкать или взаимодействовать с элементом, простоГоворя elementLocator.Click () (если реализовано как расширение) или ClickElement (elementLocator).

Я пытаюсь полностью избежать необходимости писать тесты, такие как: Driver.FindElement (elementLocator) .Click ().

Я хотел узнать мнение сообщества и, возможно, я полностью наблюдаю за чем-то очевидным.

1 Ответ

1 голос
/ 16 мая 2019

Вам не нужно автоматизировать все страницы или захватывать все объекты.Что вам нужно сделать, это захватить все, что требуется для ваших тестов.Модель Page Object предназначена для минимизации фактора «изменения» в вашей тестовой среде и, таким образом, минимизирует объем работы, который потребуется для применения любых изменений в будущем.

Если вы используете PageFactoryВам не нужно писать driver.findElement(By.(...)).click() для каждого из элементов.Вместо этого ваш код может выглядеть следующим образом:

public class SomePage {
    @FindBy(id = "some_id");
    private WebElement button;

    private WebDriver driver;

    public SomePage(WebDriver driver) {
        this.driver = driver;
    }

    public SomePage clickButton() {
        button.click();
        return this;
    }

    public String getTitle() {
        return driver.getTitle();
    }
}

Таким образом, вам не нужен класс super с каким-то необычным click методом.Это, конечно, если поведение click по умолчанию вам подходит.Если вы хотите ввести wait, Actions и так далее, не стесняйтесь создавать метод в суперклассе, который будет делать именно это.Затем конструктор базового класса вызовет super(driver), а суперкласс должен будет выполнить метод PageFactory.initElements(driver, this).Таким образом, ваш код хотел бы что-то вроде этого:

public class BasePage {
    private WebDriver driver;

    protected BasePage(WebDriver driver) {
        this.driver = driver;
    }

    protected void superClick(By elementLocator) {
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wdWait.until(ExpectedConditions
            .presenceOfElementLocated(By.cssSelector("selector"))).click();
    }
}

public class SomePage extends BasePage{

    private static final By button = By.cssSelector("some_selector");

    private WebDriver driver;

    public SomePage(WebDriver driver) {
        super(driver);
        this.driver = driver;
    }

    public SomePage clickButton() {
        superClick(button);
        return this;
    }

    public String getTitle() {
        return driver.getTitle();
    }
}

Ожидание является лишь примером для объяснения общей идеи.

РЕДАКТИРОВАТЬ

СPageFactory не следует использовать согласно комментариям и этому ответу: Почему следует избегать Page Factory Я отредактировал свой ответ.Я оставляю здесь оба примера и решение о том, как он хочет перейти к ОП.

Так или иначе, чего вы хотите достичь в итоге, это method chaining.Таким образом, ваш тест читабелен, может быть хорошим примером «одного теста одно утверждение» и будет выглядеть примерно так:

assertEquals("Title does not match.",
    expectedTitle, new LoginPage(driver)
        .openLoginPage()
        .login(user)
        .openSomePage()
        .clickButton()
        .getTitle());
...