Page Object Model (POM)
Проблема
При написании UI-тестов без структуры весь код взаимодействия со страницей — локаторы, клики, ввод текста — рассеивается прямо по телу тестовых методов. Когда верстальщик переименовывает кнопку или меняет атрибут элемента, приходится вручную искать все места в тестах, где этот элемент упоминается. Дублирование кода нарастает: один и тот же driver.findElement(By.id("search-input")) встречается в десятках тестов. Любое изменение UI превращается в болезненный рефакторинг.
Page Object Model решает эту проблему, инкапсулируя всё взаимодействие со страницей в отдельный класс. Тест описывает что нужно сделать (ввести запрос, нажать кнопку), а Page Object скрывает как это делается (какой локатор, какой тип взаимодействия). Изменение локатора требует правки только в одном месте.
Структура модуля
page-object-model/
├── build.gradle
└── src/
└── test/
└── java/
└── dev/shipovalov/pom/
├── GoogleSearchPage.java # POM главной страницы Google
├── GoogleResultsPage.java # POM страницы результатов поиска
└── PageObjectModelTest.java # Тест, использующий Page Objects
Классы страниц расположены в
src/test, так как в данном модуле они используются исключительно в тестовом контексте. В реальных проектах Page Objects чаще выносят вsrc/mainдля переиспользования между несколькими тестовыми модулями.
Ключевые классы
| Класс | Назначение |
|---|---|
GoogleSearchPage |
Инкапсулирует поисковую форму: локатор поля ввода, метод search(String query)
|
GoogleResultsPage |
Инкапсулирует страницу результатов: получение заголовка, списка результатов |
PageObjectModelTest |
Тест, работающий только через методы Page Objects, без прямых вызовов WebDriver |
Пример использования
// Без POM — хрупкий код, локаторы разбросаны по тесту
driver.findElement(By.name("q")).sendKeys("Selenium");
driver.findElement(By.name("btnK")).click();
String title = driver.getTitle();
// С POM — читаемый тест, детали скрыты в Page Object
GoogleSearchPage searchPage = new GoogleSearchPage(driver);
GoogleResultsPage resultsPage = searchPage.search("Selenium");
assertThat(resultsPage.getTitle()).contains("Selenium");
Запуск тестов
./gradlew :page-object-model:test
Отчёт о результатах: page-object-model/build/reports/tests/test/index.html