Перед тем, как изучать паттерн Page Object Model, давайте разберем, почему его нужно использовать?
Начинать автоматизировать тесты используя Selenium WebDriver – кажеться простым заданием. Необходимо лишь находить элементы, выполнять действия над ними и т.д.
Рассмотрим простой пример логина на сайт:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class NoPOMTestAutoQALogin { /** * This test case will login in http://autoqa.pp.ua/wp-login.php * Login to application * Verify the home page using Dashboard message */ @Test(priority=0) public void test_Home_Page_Appear_Correct(){ WebDriver driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("http://autoqa.pp.ua/wp-login.php"); //Find user name and fill user name driver.findElement(By.id("user_login")).sendKeys("subscriber"); //find password and fill it driver.findElement(By.id("user_pass")).sendKeys("2016subscriberpasssword2016ok"); //click login button driver.findElement(By.id("wp-submit")).click(); String homeText = driver.findElement(By.xpath("//div[@id='profile-page']/h2")).getText(); //verify login success Assert.assertTrue(homeText.toLowerCase().contains("profile")); } } |
Как можно заметить, все, что мы делаем, – это находим элементы на странице и делаем над ними определенные действия.
Это небольшой скрипт. Его поддержка выглядит простой, но с увеличением количества тестов, добавляя все больше строк кода, – она становится сложнее.
Наибольшей проблемой поддержки есть то, что 10 разных скриптов используют тот же самый код. И изменения одного элемента (например, изменение верстки сайта девелоперами), приведет к изменению всех 10 тестов.
Более лучший подход в поддержке тестов – это создание отдельного класса, который будет находить элементы на странице, заполнять или проверять их. Класс может использоваться в коде тестов, использующих элементы этого класса. В будущем в случае изменений нам необходимо будет только сделать правки в одном классе, а не во всех 10 тестах.
Этот подход называется Page Object Model(POM). POM паттер делает код более читабельным, поддерживаемым и повторно используемым.
Что такое POM?
- Page Object Model – это паттер проектирования для создания Object Repository для веб элементов UI.
- Согласно этому паттерну – для каждой страницы приложения/сайта должен быть определен соответствующий класс.
- Этот класс Page будет искать все WebElements на странице и также содержать методы для работы с ними.
- Названия этих методов должны соответствовать действиям, который они выполняют, например метод ожидания, пока элемент появится – waitForPaymentScreenDisplay().
Конечный проект выглядит следующим образом:
Преимущества POM
- Page Object Patten объявляет элементы отдельно от реализации теста. Эта концепция деалет наш код более понятным.
- Вторым преимуществом есть то, что независимость класса объектов от реализации теста позволяет использовать этот репозиторий в разных целях и с разными для выполнения тестов. Например, мы можем интегрировать POM с TestNG/JUnit для функционального тестирования, а также с JBehave/Cucumber для приемочного тестирования.
- Кода становится меньше и он более оптимизирован. Его можно повторно использовать.
- Методы получают более реальные имена и отображают выполненное действие на UI, например, gotoHomePage().
Как внедрить POM ?
Ниже представлена базовая структура Page object model (POM), где все элементы и методы вынесены в отдельный класс. Операции, такие как проверка должны быть отделены от тестового метода.
Рассмотрим на примере
Мы будем работать над 2 страницами:
- Страница входа
- Главная страница
Согласно этому мы создадим 2 POM класса:
Класс AutoQALogin:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class AutoQALogin { WebDriver driver; By userName = By.id("user_login"); By password = By.id("user_pass"); By login = By.id("wp-submit"); public AutoQALogin(WebDriver driver){ this.driver = driver; } //Set user name in textbox public void setUserName(String strUserName){ driver.findElement(userName).sendKeys(strUserName); } //Set password in password textbox public void setPassword(String strPassword){ driver.findElement(password).sendKeys(strPassword); } //Click on login button public void clickLogin(){ driver.findElement(login).click(); } /** * This POM method will be exposed in test case to login in the application * @param strUserName * @param strPasword * @return */ public void loginToAutoQA(String strUserName,String strPasword){ //Fill user name this.setUserName(strUserName); //Fill password this.setPassword(strPasword); //Click Login button this.clickLogin(); } } |
Класс AutoQAHomePage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class AutoQAHomePage { WebDriver driver; By homePageName = By.xpath("//div[@id='profile-page']/h2"); public AutoQAHomePage(WebDriver driver){ this.driver = driver; } //Get the Page name from Home Page public String getHomePageDashboardName(){ return driver.findElement(homePageName).getText(); } } |
Класс тестов TestAutoQALogin :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
package test; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import PageFactory.AutoQAHomePage; import PageFactory.AutoQALogin; public class TestAutoQALogin { WebDriver driver; AutoQALogin objLogin; AutoQAHomePage objHomePage; @BeforeTest public void setup(){ driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("http://autoqa.pp.ua/wp-login.php"); } /** * This test case will login in http://autoqa.pp.ua/wp-login.php * Login to application * Verify the home page using Dashboard message */ @Test(priority=0) public void test_Home_Page_Appear_Correct(){ //Create Login Page object objLogin = new AutoQALogin(driver); //login to application objLogin.loginToAutoQA("subscriber", "subscriberpass"); // go the next page objHomePage = new AutoQAHomePage(driver); //Verify home page Assert.assertTrue(objHomePage.getHomePageDashboardName().toLowerCase().contains("profile")); } } |
Скачать проект можно по ссылке. Он также содержит наработке по другому паттерну Page Factory, который мы рассмотрим в следующей статье.