Если вы тестируете веб-интерфейсы, вы наверняка задумывались о том, как сделать взаимодействие с веб-страницами в тестах максимально удобным.
Шаблон проектирования Page Object очень хорошо известен среди тестировщиков.
Но, несмотря на множество преимуществ, этот подход имеет и некоторые недостатки, которые сильно затрудняют его использование.
Наиболее значимые из них:
- невозможность повторного использования объектного кода страницы для страниц с одинаковыми элементами;
- плохая читаемость и ненаглядность кода страниц с большим количеством элементов;
- отсутствие типизации элементов.
Он расширяет концепцию шаблона Page Object и делает взаимодействие с элементами на веб-страницах простым, гибким и удобным.
Мы не будем останавливаться на описании самого паттерна и его принципов, поскольку большинство из вас наверняка с ним знакомы.
Если кто-то с ним не встречался, то узнать о нем можно из этого почта или мастер класс .
Кроме того, когда мы говорим об использовании шаблона Page Object, мы будем иметь в виду именно его.
Реализация Java в среде Selenium WebDriver .
Повторное использование кода
Представьте, что вам нужно написать тесты не для отдельной страницы, а для всего веб-сервиса.На его страницах наверняка будут общие блоки элементов: хедеры, футеры, возможно какие-то одинаковые формы и т. д. Например, на главной странице Яндекса есть форма поиска, которая сохраняется при переходе на страницу с результатами поиска.
.
Встречается он и на других сервисах Яндекса: например, на Яндекс.
Авто, Яндекс.
Маркет и Яндекс.
Работа.
Форму авторизации также можно увидеть не только на главной странице, но и, например, на странице Яндекс.
Паспорта или на Яндекс.
Маркете.
Логика взаимодействия с общими блоками на каждой странице абсолютно одинакова.
Но когда вам понадобится написать для этих страниц страничные объекты, вы будете вынуждены в каждой из них дублировать код, реализующий взаимодействие с этими блоками.
Вы, наверное, уже поняли, к чему я клоню? Да-да, было бы здорово иметь возможность описывать блоки элементов и логику взаимодействия с ними отдельно, а затем собирать из них объекты страниц.
И платформа HTML Elements позволяет вам это сделать.
Например, давайте используем его для описания формы поиска:
А также форма авторизации:@Block(@FindBy(className = "b-head-search")) public class SearchArrow extends HtmlElement { @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "http://input[@type='submit']") private WebElement searchButton; public void search(String request) { requestInput.sendKeys(request); searchButton.click(); } }
@Block(@FindBy(className = "b-domik__form"))
public class AuthorizationForm extends HtmlElement {
@FindBy(id = "b-domik-username")
WebElement loginField;
@FindBy(id = "b-domik-password")
WebElement passwordField;
@FindBy(xpath = "http://input[@type='submit']")
WebElement submitButton;
public void login(String login, String password) {
loginField.sendKeys(login);
passwordField.sendKeys(password);
submitButton.click();
}
}
Тогда объект страницы для главной страницы Яндекса будет выглядеть так:
public class SearchPage {
private SearchArrow searchArrow;
private AuthorizationForm authorizationForm;
// Other blocks and elements here
public SearchPage(WebDriver driver) {
HtmlElementLoader.populatePageObject(this, driver);
}
public void search(String request) {
searchArrow.search(request);
}
public void login(String login, String password) {
authorizationForm.login(login, password);
}
// Other methods here
}
Кстати, вы заметили, что селекторы элементов блока устанавливаются относительно селектора самого блока? Это очень удобно, так как блок можно расположить на разных страницах с помощью разных селекторов.
При этом внутренняя структура блока не изменится.
В этом случае при включении блока в объект страницы достаточно перегрузить селектор самого блока.
Например, на страницах сервиса Яндекс.
Авто форма поиска должна осуществляться иначе, чем на главной: public class AutoHomePage {
@FindBy(className = "b-search")
private SearchArrow searchArrow;
// Other blocks and elements here
public AutoHomePage(WebDriver driver) {
HtmlElementLoader.populatePageObject(this, driver);
}
public void search(String request) {
searchArrow.search(request);
}
// Other methods here
}
Читабельность и видимость
Чтобы полностью покрыть тестами ту или иную страницу веб-сервиса, вам потребуется задействовать все его элементы.И их может быть много.
Например, на главной странице Яндекс.
Авто есть форма для поиска автомобиля по параметрам.
В нем уже более 30 элементов, включая расширенный поиск, а также список марок автомобилей, новостной блок, блок автомобильных новостей и т.д.
Если мы напишем объект страницы для этой страницы, используя только возможности фреймворка Selenium WebDriver, мы получим очень большой класс с длинным канвасом элементов и огромным количеством методов, реализующих взаимодействие со всеми этими элементами.
Согласитесь, такой класс будет очень непонятным и трудным для чтения.
Но если у вас есть возможность отдельно создавать блоки элементов, то и эта проблема решается.
Объект страницы будет содержать всего несколько блоков, их структура и логика взаимодействия с ними будут описаны отдельно.
Типирование элемента
В Selenium WebDriver все элементы страницы — будь то кнопка, флажок или поле ввода текста — описываются с помощью интерфейса WebElement. Поэтому он имеет множество методов, общих для элементов разных типов.Но если мы, например, взаимодействуем с кнопкой, то вряд ли нам захочется вводить туда текст. С другой стороны, страницы часто содержат сложные элементы, взаимодействие с которыми невозможно описать с помощью одного лишь WebElement. Допустим, группа переключателей, раскрывающийся список или поле выбора даты.
В обоих случаях возникает одно и то же решение: ввести типизированные элементы, которые в первом случае сузят интерфейс WebElement, а во втором реализуют взаимодействие с более сложными элементами.
Это то, что мы сделали в рамках HTML Elements.
Например, так будет выглядеть описание формы поиска с использованием типизированных элементов: @Block(@FindBy(className = "b-head-search"))
public class SearchArrow extends HtmlElement {
@FindBy(name = "text")
private TextInput requestInput;
@FindBy(xpath = "http://input[@type='submit']")
private Button searchButton;
public void search(String request) {
requestInput.sendKeys(request);
searchButton.click();
}
}
А вот так будет выглядеть описание формы выбора языка в настройках поиска, где есть выпадающий список:
@Block(@FindBy(id = "lang"))
public class LanguageSelectionForm extends HtmlElement {
@FindBy(className = "b-form__select")
private Select listOfLanguages;
@FindBy(xpath = "http://input[@type='submit']")
private Button saveButton;
@FindBy(xpath = "http://input[@type='button']")
private Button returnButton;
public void selectLanguage(String language) {
listOfLanguages.selectByValue(language);
saveButton.click();
}
}
Мы уже реализовали поддержку таких базовых элементов, как TextInput, Button, CheckBox, Select, Radio и Link. Вы также можете очень легко писать свои собственные типизированные элементы и расширять существующие.
*** Платформа HTML Elements — это инструмент, который позволяет собирать объекты страницы в виде конструктора.
Из типизированных элементов вы можете собрать нужные вам блоки, которые можно комбинировать, комбинировать между собой и собирать в объекты страницы.
Это значительно увеличивает степень повторного использования кода, делает его более читабельным и наглядным, а также упрощает написание тестов.
HTML Elements имеет открытый исходный код. Вы можете попробовать это в действии и посмотреть код по адресу GitHub .
В одном из следующих постов о тестировании в Яндексе мы подробнее поговорим о самом фреймворке.
Вы узнаете, какие еще у него есть полезные функции и как его можно использовать для удобного тестирования веб-интерфейсов.
Теги: #Разработка сайта #java #Тестирование ИТ-систем #Яндекс #тестирование веб-приложений #объект страницы #вебдрайвер #Selenium #тестирование в Яндексе #Yandex QA Tools
-
Вирусы И Этика.
19 Oct, 24 -
Правила Подготовки Скриншотов К Статьям
19 Oct, 24 -
Большой О
19 Oct, 24 -
Китай Запретил Открытие Новых Интернет-Кафе
19 Oct, 24