Page Object

Что такое Page Object Model и почему ваши тесты без неё рассыпаются

Page Object Model — это не паттерн из учебника. Это единственный способ писать тесты которые не придётся переписывать каждые две недели. Объясняем на примерах.

TM
Команда TestManager
·11 июня 2026·читать 5 мин·0% прочитано

Page Object Model — это способ организации автотестов, при котором каждая страница приложения описывается как отдельный объект с набором элементов и действий. Вместо того чтобы писать driver.find(".btn-checkout-v2-final") в сорока разных тестах, вы пишете это один раз в классе CheckoutPage и вызываете checkoutPage.clickBuy() везде. Суть — убрать дублирование и сделать тесты читаемыми.

Но давайте честно о том, почему это важно прямо сейчас, а не "когда-нибудь потом когда команда вырастет".

Проблема которую вы уже имеете, просто ещё не заметили

Представьте классический сценарий. Дизайнер переименовал класс кнопки с checkout-btn на checkout-button-primary. Мелкое изменение, пять секунд работы. Но у вас упало тридцать семь тестов. Вы открываете CI, видите красный экран, начинаете разбираться — и обнаруживаете что selector checkout-btn вкопан в каждый тест руками.

Следующие три часа вы занимаетесь поиском и заменой по кодовой базе. Находите двадцать семь вхождений, исправляете, нажимаете ещё раз "Запустить" — находите ещё восемь которые пропустили.

Это не баг. Это архитектурный долг который всегда казался "не самым срочным".

Page Object Model убирает эту проблему радикально. Selector живёт в одном месте. Меняется в одном месте. Тридцать семь тестов не знают что что-то изменилось.

Как устроен Page Object на практике

Вот что происходит без POM:

// Test A
await page.click('.checkout-btn')
await page.fill('#email-field', user.email)
await page.click('.submit-order')

// Test B (написан другим человеком, через неделю)
await page.click('[class="checkout-btn"]')
await page.fill('input[type="email"]', user.email)
await page.click('button.submit-order')

Два теста делают одно и то же. Локаторы разные, потому что написаны разными людьми в разное время. Оба работают. Оба упадут по-разному при любом рефакторинге.

Вот что происходит с POM:

// CheckoutPage.js
class CheckoutPage {
  clickCheckoutButton() { ... }
  fillEmail(email) { ... }
  submitOrder() { ... }
}

// Test A
checkoutPage.clickCheckoutButton()
checkoutPage.fillEmail(user.email)
checkoutPage.submitOrder()

// Test B
checkoutPage.clickCheckoutButton()
checkoutPage.fillEmail(user.email)
checkoutPage.submitOrder()

Идентичные действия выглядят идентично. Локатор один. Меняете в одном месте.

Три признака что вам уже нужен POM прямо сейчас

Тесты дублируют селекторы.

Если один и тот же CSS-класс или data-атрибут встречается более чем в одном тестовом файле — POM нужен вчера.

На рефакторинг верстки уходит больше часа.

Дизайнер поменял форму — вы чините тесты два дня. Это не норма. С POM — тридцать минут.

Новый человек не может прочитать тест.

Если коллега смотрит на тест и не понимает что тестируется без чтения HTML — тест написан на языке браузера, а не на языке продукта. POM переводит тесты на язык продукта.

POM и инструменты без кода

Вот что интересно: no-code инструменты типа TestManager реализуют POM под капотом автоматически. Когда вы записываете взаимодействие с кнопкой, инструмент создаёт Page Object для этой страницы сам. Вы не выбираете паттерн — он применяется по умолчанию.

Это не магия. Это просто правильное место по умолчанию.

Когда вы пишете тесты вручную, POM — это сознательное решение которое нужно принять и поддерживать. Когда инструмент делает это за вас, решение принято заранее. Это значит что команда из пяти человек с TestManager имеет ту же архитектурную дисциплину что и команда из пяти senior QA engineers с нуля построенной инфраструктурой.

Что такое хороший Page Object и что таковым не является

Хороший Page Object описывает поведение страницы, а не её реализацию. Метод proceedToCheckout() — это поведение. Метод clickButtonWithClassCheckoutBtnV2() — это реализация. Первый выживет при рефакторинге. Второй — нет.

Правила простые:

1
Один класс на одну страницу или компонент
2
Методы описывают действия пользователя, не HTML-структуру
3
Все локаторы только внутри класса, никогда снаружи
4
Нет логики тестирования внутри Page Object — только навигация и взаимодействие

Если Page Object делает assert — это неправильный Page Object. Ассерты живут в тестах. Page Object — только интерфейс к странице.

FAQ

Что такое Page Object Model (POM) простыми словами?

Page Object Model — это подход к написанию автотестов, при котором каждая страница сайта представлена отдельным классом или модулем. Этот класс содержит все элементы страницы и действия с ними. Тесты вызывают методы этого класса, а не работают напрямую с HTML. Главное преимущество — изменение вёрстки требует правок только в одном файле, а не во всех тестах.

Почему без Page Object Model тесты сложно поддерживать?

Без POM один и тот же локатор (CSS-класс, XPath, id) дублируется в десятках тестов. Когда вёрстка меняется — нужно найти и исправить каждое вхождение. Это занимает часы и сопровождается ошибками. POM централизует локаторы: меняете в одном месте — всё работает.

Нужен ли POM при использовании no-code инструментов автоматизации?

No-code инструменты, как правило, реализуют принципы POM автоматически. При записи теста инструмент фиксирует элементы страницы в централизованном хранилище. Вам не нужно думать о паттерне — он применяется по умолчанию. Это одно из ключевых преимуществ no-code подхода.

Как связаны Page Object Model и Playwright?

Playwright — это фреймворк для браузерной автоматизации. POM — это паттерн организации кода поверх любого фреймворка, включая Playwright. Вы можете использовать POM с Playwright, Selenium, Cypress или любым другим инструментом. В TestManager POM реализован на базе Playwright под капотом.

С чего начать внедрение POM в существующем проекте?

Не рефакторьте всё сразу. Начните с самой часто ломающейся страницы — скорее всего это форма оплаты или авторизации. Создайте один Page Object для неё, перенесите локаторы, запустите тесты. Убедитесь что всё работает. Потом повторите для следующей страницы. Инкрементально, без остановки разработки.

ПОДЕЛИТЬСЯ

Превратите повторяемые проверки в запускаемый регресс

Записывайте сценарии, храните их в структуре и запускайте перед каждым релизом.

Попробовать бесплатно