1. Архитектура UI-автотестов: Pytest, Selenium и POM
Архитектура UI-автотестов: Pytest, Selenium и POM
Зачем вообще нужна архитектура в UI-автотестах
UI-тесты часто начинают писать “в лоб”: открыть страницу, найти элемент, кликнуть, проверить текст. На небольшом проекте это работает, но при росте количества тестов быстро появляются проблемы:
Цель хорошей архитектуры — сделать тесты:
В этом курсе базовая связка будет такой:
Роли Pytest и Selenium в UI-тестировании
Что делает Pytest
Pytest отвечает за “тестовую инфраструктуру”:
Ключевая идея: тест должен описывать проверку, а подготовка и сервисные детали должны быть вынесены в фикстуры.
Что делает Selenium
Selenium отвечает за “управление браузером”:
Важно: Selenium — низкоуровневый инструмент. Если писать тесты напрямую на Selenium-командах, тестовый код быстро станет сложным и повторяющимся. Поэтому Selenium обычно “прячут” за POM-слоем.
Что такое Page Object Model (POM)
Page Object Model — это подход, где каждая страница (или значимый компонент) описывается отдельным классом, который:
login, search, add_to_cart)Хороший Page Object не должен “знать” про проверки теста. Он описывает как взаимодействовать со страницей, а тест описывает что проверить.
Полезное чтение по паттерну: Martin Fowler — PageObject
Слои в типичном UI-автопроекте
Удобно мыслить проект как несколько уровней ответственности.
Уровень тестов
Тесты в идеале выглядят как сценарии:
Тесты не должны содержать:
WebDriverWait прямо в тестеУровень Page Objects
Page Object:
is_opened()), но не бизнес-ассерты тестаБазовый слой взаимодействия (BasePage / wrappers)
Это слой, где живут:
Идея: все нестабильные и повторяющиеся части Selenium сосредоточены в одном месте.
Конфигурация и тестовые данные
Отдельно стоит хранить:
Рекомендуемая структура проекта
Один из рабочих вариантов структуры (её можно адаптировать под командные стандарты):
Ключевые принципы:
conftest.py содержит фикстуры PytestМинимальный каркас: Pytest + WebDriver фикстура
Ниже пример базовой фикстуры, которая создаёт и закрывает драйвер. В реальном проекте вы добавите настройку браузера, headless-режим, размер окна и т.д.
Почему полезно делать именно так:
yield гарантирует корректное освобождение ресурсовdriver как аргументBasePage: единая точка для ожиданий и действий
Selenium-тесты становятся стабильнее, когда ожидания стандартизированы и не размазаны по проекту.
Здесь важны две идеи:
click/type/text_of — это контракт взаимодействия, одинаковый для всех страницДокументация по ожиданиям: Selenium — Waits
Page Object: пример страницы логина
Page Object обычно содержит:
Обратите внимание:
Тест как сценарий: минимум деталей Selenium
Признаки “здорового” теста:
WebDriverWaitГде заканчивается POM и начинаются фикстуры
Частая ошибка — пытаться сделать “всё в POM” или “всё в фикстурах”. Практичное разделение:
Если авторизация нужна в каждом тесте, это хороший кандидат на фикстуру:
Локаторы: как договориться с командой
Чтобы проект был поддерживаемым, полезно принять правила:
data-testid, data-qa, idЕсли в продукте можно влиять на разметку, самый практичный подход — внедрять data-* атрибуты специально под автотесты.
Компоненты вместо страниц (когда POM расширяется)
Когда в приложении много повторяющихся элементов (хедер, меню, таблицы, модальные окна), полезно выделять компоненты.
Идея:
Header содержит локаторы и методы для шапкиТак уменьшается дублирование и упрощается поддержка.
Типовые ошибки архитектуры UI-автотестов
Что будет дальше в курсе
В следующих материалах мы будем наращивать этот каркас: