← Назад к вопросам

Что такое Page Object Model (POM)?

1.3 Junior🔥 192 комментариев
#Теория тестирования

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое 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 требует дополнительных усилий на старте проекта, но многократно окупается на этапе поддержки и масштабирования тестовой кодовой базы, особенно в условиях частых изменений пользовательского интерфейса.