Несколько советов по созданию page object классов здорового человека

И снова здравствуйте. В преддверии старта курса «Java QA Engineer» подготовили перевод еще одной полезной статьи.



Это начало нового года, и многие люди во всем мире принимают решение уделять больше внимания своему здоровью. Это прекрасно! На самом деле, ваши тесты для фронтенда также нуждаются в таком решении.

Самым популярным паттерном проектирования, используемым в кодовых базах тестирования веб-UI, является паттерн Page Object Model (POM). Этот паттерн предполагает моделирование класса для представления одной страницы тестируемой системы. На основе этой модели, класс будет содержать свойства, которые представляют элементы страницы пользовательского интерфейса и методы, которые взаимодействуют с этими элементами.

Взяв за пример эту страницу входа в наше приложение, давайте обсудим советы по созданию класса с использованием POM.



КЛАСС


Мы создаем единственный класс в нашей среде автоматизации для представления этой страницы. Рекомендуется убедиться, что имя класса соответствует странице в приложении, чтобы другие разработчики могли быстро найти класс, связанный с данной страницей пользовательского интерфейса.

Итак, в этом примере мы создадим класс с именем LoginPage.

public class LoginPage {
    
    private WebDriver driver;
 
    public LoginPage(WebDriver driver){
        this.driver = driver;
    }
}


СВОЙСТВА


LoginPage должен содержать свойства для каждого из элементов на странице, которые будут использоваться в ваших тестах. Значения этих свойств являются указателями на элементы на реальной странице. Определяя эти локаторы в одном месте, вам не нужно будет хардкодить их в каждом месте, где вы их используете — таким образом, устраняя дублирование.

private By usernameField        = By.id("username");
private By passwordField        = By.id("password");
private By signInButton     	= By.id("log-in");
private By rememberMeCheckbox   = By.id("rememberMe");
private By twitterIcon          = By.id("twitterIcon");
private By facebookIcon     	= By.id("fbIcon");
private By linkedInIcon     	= By.id("linkedInIcon");
private By errorMessage     	= By.id("alert");


МЕТОДЫ


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

ДОБАВЬТЕ ГЕТТЕРЫ И СЕТТЕРЫ


Целью POM классов является установка (set) и получение (get) состояния вашего приложения.Так что вам понадобятся соответствующие методы для этого.

Например, нам обязательно нужно установить поля username и password, поэтому необходимо добавить для них сеттеры.

public void setUsername(String username) {
    driver.findElement(usernameField).sendKeys(username);
}
 
public void setPassword(String password) {
    driver.findElement(passwordField).sendKeys(password);
}


public String getErrorMessage() {
    return driver.findElement(errorMessage).getText();
}


ДОБАВЛЯЙТЕ ТОЛЬКО ТО, ЧТО НУЖНО В НАСТОЯЩЕЕ ВРЕМЯ


Обратите внимание, мы не добавляли геттеры и сеттеры для каждого поля, потому что они не нужны нам в наших тестах. Добавляйте только то, что нужно в данный момент. Вы всегда можете добавить больше, если это потребуется для нового теста. Это избавит вас от необходимости поддерживать неиспользуемый код.

ПЕРЕХОДЫ ДОЛЖНЫ ВОЗВРАЩАТЬ НОВЫЕ ОБЪЕКТЫ


Вам также понадобятся методы для нажатия кнопок и ссылок. Однако, когда ваш клик приводит к смене страницы, ваш метод должен возвращать дескриптор класса, представляющего страницу пользовательского интерфейса, на которую вы перешли.

Например, если нажатие кнопки входа ведет к главной странице вашего приложения, тогда ваш метод должен вернуть дескриптор класса, представляющего эту главной страницу.

public HomePage clickSignInButton() {
    driver.findElement(signInButton).click();
    return new HomePage();
}


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

НЕ БОЙТЕСЬ СОЗДАВАТЬ МЕТОДЫ ДЛЯ УДОБСТВА
Прямо сейчас для входа в приложение потребуется вызвать как минимум три метода (setUsername, setPassword и clickSignInButton). Поскольку они обычно используются вместе, имеет смысл предоставить в вашем классе удобный метод входа, чтобы ваши тесты могли вызывать только один метод.

public HomePage login(String username, String password) {
    setUsername(username);
    setPassword(password);
    return clickSignInButton();
}


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

УЧИТЫВАЙТЕ СОСТОЯНИЯ


Для чекбокс-элементов (или других переключателей) простое нажатие на них может не соответствовать желаемому замыслу теста. Например, что если ваш тест хочет, чтобы чекбокс был установлен, но он уже установлен? Вызов метода клика в таком случае даст вам противоположный результат. Вместо этого сделайте свой метод более сложным, внедрив логику, которая будет ставить флажок только в том случае, если именно такой результат необходим пользователю. Чтобы сделать это, вместо слепого клика, примите аргумент, который указывает намерение (т. е. нам нужно, чтобы он был выбран или нет) и действовал соответственно.

public boolean isRememberUsernameChecked() {
    return driver.findElement(rememberMeCheckbox).isSelected();
}
 
public void setRememberUsername(boolean checkIt) {
    boolean alreadySelected = isRememberUsernameChecked();
 
    //прожимается, только если цель теста не соответствует текущему состоянию 
    if( (checkIt && !alreadySelected) || (!checkIt && alreadySelected) ) {
        driver.findElement(rememberMeCheckbox).click();
    }
}


СОХРАНЯЙТЕ НЕЙТРАЛЬНОСТЬ POM КЛАССОВ


Ваш POM класс должен быть нейтральным объектом, который взаимодействует и собирает информацию о вашем приложении. Постарайтесь, чтобы ваши методы были нейтральными и убедитесь, что они достаточно универсальны, чтобы их можно было использовать в любом тесте, который хочет взаимодействовать со страницей. Это означает, что в эти методы не должны входить утверждения.

Например, что если наш метод, который получает сообщение об ошибке, также не проходит тест, если сообщение является видимым?

//Так не надо делать. Не используйте это
public String getErrorMessage() {
    String message = driver.findElement(errorMessage).getText();
    if(message.isDisplayed()){
        assert.fail(message);
    }
    return message;
}


Я не могу повторно использовать этот метод для тестов, в которых я хочу убедиться, что отображается сообщение об ошибке, если имя пользователя или пароль неверны или не указаны. Это связано с тем, что POM класс взял на себя задачу определить, что отображение сообщения об ошибке является ошибкой; в то время как в этих случаях это не так. Вместо этого просто верните состояние и позвольте тесту определить, что оно означает.

public String getErrorMessage() {
    return driver.findElement(errorMessage).getText();
}



ЗДОРОВЫЙ КОД ПРЕДШЕСТВУЕТ ЗДОРОВЫМ ТЕСТАМ


Эти советы должны помочь вам разработать хорошие работоспособные классы, реализующие паттерн проектирования Page Object Model. Использование этого паттерна способствует разделению полномочий (например, тесты и управлением состоянием), уменьшает дублирование кода и предоставляет повторно используемые методы. Удачного тестирования!

Приглашаем всех на бесплатный вебинар, в рамках которого вы узнаете все подробности о курсе. А также мы займемся практикой и соберем из подручных средств заглушку для третьей системы и поговорим, как ее адаптировать для целей тестирования.
Источник: habr.ru