Что такое паттерн Page Object?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Page Object Pattern: Паттерн проектирования в автоматизации
Что такое Page Object?
Page Object — это паттерн проектирования (design pattern) для автоматизации UI тестирования, который инкапсулирует все элементы страницы и операции с ними в отдельный класс. Основная идея — отделить логику тестов от деталей взаимодействия с интерфейсом.
Основные принципы Page Object
1. Инкапсуляция элементов страницы
- Все селекторы локаторы элементов находятся в одном месте
- Тесты не знают о внутреннем устройстве страницы
- Изменения в HTML не влияют на тесты, только на Page Object
2. Методы для операций
- Каждый метод представляет действие пользователя
- Методы возвращают либо результат, либо новый Page Object
- Логика взаимодействия централизована
3. Читаемость и переиспользование
- Тесты становятся простыми и понятными
- Один Page Object используется многими тестами
- Легче поддерживать и менять
Структура Page Object
Типичная структура класса:
class LoginPage:
- ЭЛЕМЕНТЫ (locators)
- username_input = "input[id='username']"
- password_input = "input[id='password']"
- login_button = "button[type='submit']"
- error_message = ".error-alert"
- МЕТОДЫ (actions)
- enter_username(username)
- enter_password(password)
- click_login_button()
- get_error_message()
Практический пример на Python + Selenium
Без Page Object (плохо):
def test_login_without_page_object():
driver = webdriver.Chrome()
driver.get("https://example.com/login")
# Элементы жестко закодированы в тесте
username_input = driver.find_element(By.ID, "username")
password_input = driver.find_element(By.ID, "password")
login_button = driver.find_element(By.CSS_SELECTOR, "button[type='submit']")
username_input.send_keys("testuser")
password_input.send_keys("password123")
login_button.click()
# Проверка
dashboard = driver.find_element(By.CLASS_NAME, "dashboard")
assert dashboard.is_displayed()
С Page Object (хорошо):
from selenium import webdriver
from selenium.webdriver.common.by import By
class LoginPage:
def __init__(self, driver):
self.driver = driver
# Элементы (locators)
self.username_input = (By.ID, "username")
self.password_input = (By.ID, "password")
self.login_button = (By.CSS_SELECTOR, "button[type='submit']")
self.error_message = (By.CLASS_NAME, "error-alert")
# Методы для действий
def enter_username(self, username):
self.driver.find_element(*self.username_input).send_keys(username)
return self
def enter_password(self, password):
self.driver.find_element(*self.password_input).send_keys(password)
return self
def click_login(self):
self.driver.find_element(*self.login_button).click()
return self
def get_error_text(self):
return self.driver.find_element(*self.error_message).text
class DashboardPage:
def __init__(self, driver):
self.driver = driver
self.dashboard = (By.CLASS_NAME, "dashboard")
def is_displayed(self):
return self.driver.find_element(*self.dashboard).is_displayed()
# Сам тест — простой и читаемый
def test_login_with_page_object():
driver = webdriver.Chrome()
driver.get("https://example.com/login")
login_page = LoginPage(driver)
dashboard = login_page.enter_username("testuser") \
.enter_password("password123") \
.click_login()
dashboard_page = DashboardPage(driver)
assert dashboard_page.is_displayed()
Преимущества Page Object Pattern
1. Maintainability (Поддерживаемость)
- Изменение селектора → правка в одном месте
- Старое: меняешь 100 тестов; новое: меняешь 1 Page Object
2. Readability (Читаемость)
- Тесты описывают сценарии на бизнес-языке
login_page.enter_username("test")понятнее чемfind_element(By.ID, "username").send_keys("test")
3. Reusability (Переиспользование)
- Один Page Object используется в разных тестах
- Избежание дублирования кода
4. Reliability (Надежность)
- Централизованное управление waits и retries
- Меньше ошибок из-за нестабильного UI
5. Scalability (Масштабируемость)
- Легко добавлять новые методы
- Легко расширять тестовое покрытие
Расширение: Page Object Model (POM)
POM — это полная архитектура, построенная на Page Object:
- Base Page Object (общие методы для всех страниц)
- Наследование и инкапсуляция
- Factory patterns для создания page objects
Пример с базовым классом:
class BasePage:
def __init__(self, driver):
self.driver = driver
def find_element(self, locator):
return self.driver.find_element(*locator)
def wait_for_element(self, locator, timeout=10):
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
return WebDriverWait(self.driver, timeout).until(
EC.presence_of_element_located(locator)
)
class LoginPage(BasePage):
def __init__(self, driver):
super().__init__(driver)
self.username_input = (By.ID, "username")
# ... остальные методы
Best Practices Page Object
1. Один Page Object = одна страница
- Не смешивай элементы разных страниц
2. Методы возвращают Page Object
- Позволяет цепочку вызовов (fluent interface)
page.login(user).fill_form().submit()
3. Избегай conditional logic в Page Objects
- Логика проверок в тестах, не в Page Object
- Page Object только взаимодействует с UI
4. Явные waits вместо sleep
# Плохо
time.sleep(2)
# Хорошо
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located(self.success_message)
)
5. Понятные имена методов
submit_login_form()вместоclick_btn1()- Названия должны отражать бизнес-действия
Альтернативные подходы
Screenobject/Screen Object — для мобильных приложений (Appium) Business Object — более высокий уровень абстракции API Object — паттерн для API тестирования
Заключение
Page Object Pattern — это фундаментальный паттерн в автоматизации UI тестирования. Он делает тесты более читаемыми, поддерживаемыми и надежными. Практически все зрелые фреймворки автоматизации строятся на основе Page Object или его вариаций. Освоение этого паттерна критично для QA инженера, работающего с автоматизацией.