Ответ
Page Object (PO) — это ключевой паттерн проектирования в автоматизации UI-тестирования, который инкапсулирует структуру и поведение веб-страницы (или её компонента) в отдельный класс. Каждый такой класс содержит локаторы элементов и методы для взаимодействия с ними, отделяя тестовую логику от деталей реализации страницы.
Основные преимущества с точки зрения QA:
- Повышение сопровождаемости: При изменении верстки (например, ID элемента) правки вносятся только в один класс Page Object, а не во все тесты.
- Улучшение читаемости: Тестовые сценарии становятся лаконичными и понятными, так как используют высокоуровневые методы вроде
loginPage.login("user", "pass"). - Устранение дублирования кода: Логика работы со страницей выносится в одно место.
- Упрощение повторного использования: Компоненты (например, хедер или футер) можно вынести в отдельные Page Object и использовать на разных страницах.
Пример реализации на Java с Selenium WebDriver:
public class LoginPage {
private WebDriver driver;
// Локаторы элементов страницы
private By usernameField = By.id("username");
private By passwordField = By.id("password");
private By loginButton = By.id("loginBtn");
private By errorMessage = By.cssSelector(".alert.error");
public LoginPage(WebDriver driver) {
this.driver = driver;
}
// Метод для выполнения входа
public HomePage loginWithValidCredentials(String username, String password) {
driver.findElement(usernameField).sendKeys(username);
driver.findElement(passwordField).sendKeys(password);
driver.findElement(loginButton).click();
return new HomePage(driver); // Возвращаем Page Object следующей страницы
}
// Метод для негативного теста
public String loginWithInvalidCredentials(String username, String password) {
driver.findElement(usernameField).sendKeys(username);
driver.findElement(passwordField).sendKeys(password);
driver.findElement(loginButton).click();
return driver.findElement(errorMessage).getText(); // Возвращаем текст ошибки
}
}
Использование в тесте (JUnit):
@Test
public void successfulLoginTest() {
LoginPage loginPage = new LoginPage(driver);
HomePage homePage = loginPage.loginWithValidCredentials("testUser", "testPass");
assertTrue(homePage.isUserMenuDisplayed());
} Ответ 18+ 🔞
А, ну вот, смотри, объясняю на пальцах, что за зверь такой — Page Object. Это, блядь, как если бы ты пришёл в бар, а там вместо того чтобы каждый раз бармену объяснять: «Дай мне стакан, налей туда водки, кинь лёд, дольку лайма» — у тебя просто есть кнопка «Мохито». Нажал — и всё, готово. Вот Page Object — это и есть такая кнопка, только для веб-страницы.
Если по-умному, то это паттерн, который всю эту хуйню — поля ввода, кнопки, таблицы — засовывает в отдельный класс. Чтобы твои тесты не превращались в адский спагетти-код, где перемешаны «найти элемент по ID» и «проверить, что заказ создался». Теперь это два разных мира.
Ну и нахуя это надо, спросишь ты? А вот нахуя:
- Чинить в одном месте. Представь, фронтендеры взяли и поменяли
id="loginBtn"наdata-qa="submit". Без Page Object тебе пришлось бы, ёпта, бегать по всем сотням тестов и менять этот локатор. Это пиздец. А с Page Object — ты зашёл в один классLoginPage, поправил одну строчку, и всё, ты красавчик. Сопровождаемость — овердохуища. - Читать как книжку. Тест теперь выглядит не как шифровка для посвящённых, а как нормальная инструкция:
loginPage.enterCredentials(...); homePage.checkOrder();. Даже менеджер, если заглянет, может примерно понять, что происходит. Удивление пиздец, правда? - Не повторяться. Логику «как залогиниться» ты пишешь ОДИН РАЗ в методе
login. И потом просто вызываешь её из двадцати разных тестов. Никакого копипаста, который потом, когда надо что-то поменять, выстрелит тебе в жопу. - Собирать из кубиков. Сделал класс для шапки сайта (
HeaderPage) — и таскай его на все страницы, где эта шапка есть. Удобно, чё.
Смотри, как это выглядит в коде (Java + Selenium):
public class LoginPage {
private WebDriver driver;
// Вот тут мы храним все эти ебучки-локаторы, чтоб они были в одном месте
private By usernameField = By.id("username");
private By passwordField = By.id("password");
private By loginButton = By.id("loginBtn");
private By errorMessage = By.cssSelector(".alert.error");
public LoginPage(WebDriver driver) {
this.driver = driver;
}
// Метод для нормального входа. Залогинился — и тебя перекинуло на домашнюю страницу
public HomePage loginWithValidCredentials(String username, String password) {
driver.findElement(usernameField).sendKeys(username);
driver.findElement(passwordField).sendKeys(password);
driver.findElement(loginButton).click();
return new HomePage(driver); // Возвращаем уже следующий Page Object
}
// А это для негативщины. Ввёл хуйню — получи сообщение об ошибке
public String loginWithInvalidCredentials(String username, String password) {
driver.findElement(usernameField).sendKeys(username);
driver.findElement(passwordField).sendKeys(password);
driver.findElement(loginButton).click();
return driver.findElement(errorMessage).getText();
}
}
А вот как этим потом в тесте пользуются:
@Test
public void successfulLoginTest() {
// Создаём объект страницы логина
LoginPage loginPage = new LoginPage(driver);
// Вызываем метод — и нас сразу кидает на HomePage
HomePage homePage = loginPage.loginWithValidCredentials("testUser", "testPass");
// И проверяем, что зашли успешно
assertTrue(homePage.isUserMenuDisplayed());
}
Короче, чувак, если не хочешь, чтобы твоя автотестовая фантастика превратилась в хоррор с тоннами одинакового кода и вечными правками — бери Page Object на вооружение. Изначально, конечно, придётся немного подумать, как структурировать, но потом ты сам себе спасибо скажешь. Терпения, блядь, ноль — поддерживать кучу размазанных по тестам локаторов. А так — красота.