Что такое Page Object Model (POM)?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Page Object Model (POM)?
Page Object Model (POM) — это широко распространённый паттерн проектирования в автоматизации тестирования веб-приложений, который повышает поддерживаемость, читаемость и устойчивость тестового кода. Его основная идея заключается в инкапсуляции логики работы с элементами веб-страницы в отдельные классы, называемые Page Objects (Объекты страницы). Каждый такой класс соответствует одной веб-странице (или значимому фрагменту интерфейса) и содержит:
- Локаторы элементов (селекторы XPath, CSS и т.д.).
- Методы для взаимодействия с этими элементами (клик, ввод текста, получение атрибутов).
- Методы, инкапсулирующие бизнес-логику пользовательских сценариев на данной странице.
Таким образом, тестовые сценарии (например, написанные с использованием JUnit, TestNG или pytest) работают не напрямую с низкоуровневыми Selenium-командами и локаторами, а через абстракцию, предоставляемую Page Object.
Ключевые принципы и преимущества POM
- Инкапсуляция деталей реализации: Все изменения в вёрстке страницы (например, обновление
idилиclassэлемента) вносятся в одном месте — внутри соответствующего класса Page Object. Тесты при этом остаются неизменными. - Повторное использование кода: Методы для взаимодействия с элементами (например,
login(username, password)илиsearchForProduct(productName)) могут многократно использоваться в различных тестах. - Улучшенная читаемость тестов: Тестовые сценарии становятся лаконичными и читаются почти как естественный язык, фокусируясь на что сделать, а не на как сделать.
- Снижение дублирования кода: Локаторы и базовые действия с элементами не размазаны по сотням тестовых методов, а централизованы.
- Упрощение командной работы: Разработчики автотестов могут эффективно разделять работу: один создаёт и поддерживает Page Objects, другой — пишет на их основе тестовые сценарии.
Базовая структура и пример
Типичная структура проекта с POM выглядит так:
src/test/java/
├── pages/ # Пакет с Page Objects
│ ├── LoginPage.java
│ ├── HomePage.java
│ └── CartPage.java
└── tests/ # Пакет с тестовыми классами
└── LoginTest.java
Рассмотрим простой пример на Java с использованием Selenium WebDriver и JUnit.
1. Page Object для страницы логина (LoginPage.java):
package pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPage {
WebDriver driver;
// 1. Объявление локаторов элементов страницы с аннотацией @FindBy
@FindBy(id = "username")
private WebElement usernameField;
@FindBy(id = "password")
private WebElement passwordField;
@FindBy(css = "button[type='submit']")
private WebElement loginButton;
@FindBy(className = "error-message")
private WebElement errorMessage;
// 2. Конструктор для инициализации элементов через PageFactory
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
// 3. Методы для инкапсуляции действий на странице (публичное API страницы)
public void enterUsername(String username) {
usernameField.clear();
usernameField.sendKeys(username);
}
public void enterPassword(String password) {
passwordField.clear();
passwordField.sendKeys(password);
}
public void clickLoginButton() {
loginButton.click();
}
// 4. Комплексный метод, инкапсулирующий целый бизнес-сценарий
public HomePage performLogin(String username, String password) {
enterUsername(username);
enterPassword(password);
clickLoginButton();
return new HomePage(driver); // Возвращаем объект следующей страницы
}
public String getErrorMessageText() {
return errorMessage.getText();
}
}
2. Тестовый класс, который использует Page Object (LoginTest.java):
package tests;
import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import pages.LoginPage;
import pages.HomePage;
public class LoginTest {
@Test
public void testSuccessfulLogin() {
// Настройка драйвера
WebDriver driver = new ChromeDriver();
driver.get("https://example.com/login");
// Создание экземпляра Page Object
LoginPage loginPage = new LoginPage(driver);
// Использование метода Page Object для выполнения логина
HomePage homePage = loginPage.performLogin("validUser", "validPass123");
// Проверка успешного входа (например, наличие элемента на HomePage)
Assert.assertTrue("Login was not successful", homePage.isUserMenuDisplayed());
driver.quit();
}
@Test
public void testLoginWithInvalidCredentials() {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com/login");
LoginPage loginPage = new LoginPage(driver);
loginPage.performLogin("invalidUser", "wrongPass");
// Проверка сообщения об ошибке, используя метод Page Object
String actualError = loginPage.getErrorMessageText();
Assert.assertEquals("Invalid credentials", actualError);
driver.quit();
}
}
Расширенные вариации паттерна
- Page Factory: Вспомогательный класс в Selenium (как в примере выше), который упрощает инициализацию элементов с аннотациями
@FindBy. - Loadable Component Pattern: Дополнение к POM, добавляющее явные ожидания полной загрузки страницы перед взаимодействием с ней.
- Page Elements / Blocks: Для борьбы с дублированием внутри сложных Page Objects (например, хедер или футер сайта) создаются отдельные классы-компоненты, которые затем включаются в Page Objects.
Заключение
Page Object Model — это фундаментальный паттерн для построения устойчивых и легко поддерживаемых фреймворков автоматизации UI-тестирования. Он создаёт чёткое разделение ответственности между кодом, описывающим страницу приложения, и кодом, содержащим тестовую логику и утверждения (assertions). Внедрение POM требует дополнительных усилий на старте проекта, но многократно окупается на этапе поддержки и масштабирования тестовой кодовой базы, особенно в условиях частых изменений пользовательского интерфейса.