Ответ
Основное преимущество POM — это снижение стоимости поддержки и повышение читаемости автотестов за счет инкапсуляции логики взаимодействия с элементами страницы в отдельные классы.
Конкретные выгоды для проектов на Selenium/Selenide:
- Устойчивость к изменениям в верстке: Если изменился локатор кнопки
Login, его нужно поправить только в одном месте — в классеLoginPage. Без POM пришлось бы искать и править этот локатор во всех десятках тестов, где он используется. - Улучшенная читаемость и реюзабилити: Тест-код описывает что мы делаем (логинимся, добавляем товар в корзину), а не как (ищем поле, вводим текст, кликаем). Это делает тесты короче и понятнее бизнес-аналитикам.
- Единая точка для сложных взаимодействий: Если для входа нужно выполнить несколько шагов (ввести логин, пароль, решить капчу), эта логика инкапсулирована в метод
login()объекта страницы. Тесты используют этот высокоуровневый метод.
Сравнение на примере Selenide (Java):
// ПЛОХО: Локаторы и логика размазаны по тесту
@Test
public void testLoginWithoutPOM() {
open("/login");
$(By.id("username")).setValue("user");
$(By.id("password")).setValue("pass");
$(By.id("login-button")).click();
$(By.className("welcome-msg")).shouldHave(text("Welcome"));
}
// ХОРОШО: Использование POM
public class LoginPage {
private SelenideElement usernameField = $(By.id("username"));
private SelenideElement passwordField = $(By.id("password"));
private SelenideElement loginButton = $(By.id("login-button"));
private SelenideElement welcomeMessage = $(By.className("welcome-msg"));
public HomePage login(String user, String pass) {
usernameField.setValue(user);
passwordField.setValue(pass);
loginButton.click();
return new HomePage(); // Возвращаем объект следующей страницы
}
public void assertWelcomeMessage() {
welcomeMessage.shouldHave(text("Welcome"));
}
}
// Тест становится чистым и выразительным
@Test
public void testLoginWithPOM() {
LoginPage loginPage = open("/login", LoginPage.class);
HomePage homePage = loginPage.login("user", "pass");
homePage.assertUserIsLoggedIn();
}
При рефакторинге верстки изменения локаторов будут сосредоточены в классах Page Object, а не в сотнях тестовых методов.
Ответ 18+ 🔞
Слушай, а вот объясни мне, как человеку, который уже десять раз переписывал тесты из-за того, что фронтендеры кнопку переименовали. В чём, блядь, соль этого вашего Page Object Model? Ну кроме того, что это модно и все так делают?
А соль, оказывается, проще пареной репы. Всё дело в стоимости поддержки, ёпта. Представь: у тебя сотня тестов, и в каждом ты ищешь кнопку логина по id="login-btn". И тут приходит дизайнер и говорит: "Ребят, мы её переименовали в data-qa="sign-in"". Без POM тебе придётся, блядь, проходить по всем этим сотням файлов и менять локатор. Это пиздец, это ад, это терпения ноль ебать. А с POM ты идёшь в один-единственный класс LoginPage, правишь одно поле — и всё, ты красавчик. В рот мне чих-пых, вот она, магия!
И это не всё. Читаемость, сука, вырастает в овердохуища раз. Твой тест перестаёт быть инструкцией для робота: "возьми это, кликни то". Он начинает говорить на человеческом языке.
Смотри, как было раньше, пиздопроебибна история:
@Test
public void testLoginWithoutPOM() {
open("/login");
$(By.id("username")).setValue("user");
$(By.id("password")).setValue("pass");
$(By.id("login-button")).click();
$(By.className("welcome-msg")).shouldHave(text("Welcome"));
}
Что тут происходит? Хуй с горы поймёт. Какие-то поля, какие-то клики. А теперь гляди, как должно быть:
public class LoginPage {
private SelenideElement usernameField = $(By.id("username"));
private SelenideElement passwordField = $(By.id("password"));
private SelenideElement loginButton = $(By.id("login-button"));
private SelenideElement welcomeMessage = $(By.className("welcome-msg"));
public HomePage login(String user, String pass) {
usernameField.setValue(user);
passwordField.setValue(pass);
loginButton.click();
return new HomePage();
}
public void assertWelcomeMessage() {
welcomeMessage.shouldHave(text("Welcome"));
}
}
// А сам тест — чистая поэзия!
@Test
public void testLoginWithPOM() {
LoginPage loginPage = open("/login", LoginPage.class);
HomePage homePage = loginPage.login("user", "pass");
homePage.assertUserIsLoggedIn();
}
Видишь разницу? Тест теперь не про "как", а про "что". Открыл страницу логина, залогинился, проверил, что вошёл. Ядрёна вошь, да это же почти как требования читать! Любой менеджер, даже тот, который в коде ни хуя не шарит, посмотрит и скажет: "Ага, логин тестируем".
И третий козырь — сложная логика. Вот, например, если на той же странице логина нужно ещё и капчу ввести, или чекбокс "запомнить меня" нажать. Без POM ты эту поебень будешь копипастить в каждом втором тесте. А с POM ты просто добавляешь пару строк в метод login() внутри класса страницы — и все тесты автоматически начинают использовать новую, улучшенную логику. Ебать мои старые костыли, вот это эффективность!
Короче, POM — это не просто паттерн, это, блядь, способ сохранить рассудок, когда проект растёт, а фронт меняется каждую неделю. Доверия ебать ноль к их стабильности, зато с POM хоть какая-то защита есть.