POM(페이지 개체 모델) 및 페이지 팩토리 Selenium
페이지 개체 모델이란 무엇입니까?
페이지 개체 모델(POM) 웹 UI 요소에 대한 개체 저장소를 생성하는 테스트 자동화에 널리 사용되는 디자인 패턴입니다. 이 모델의 장점은 코드 중복을 줄이고 테스트 유지 관리를 향상시킨다는 것입니다.
이 모델에 따라 애플리케이션의 각 웹 페이지에는 해당 페이지 클래스가 있어야 합니다. 이 페이지 클래스는 해당 웹 페이지의 WebElements를 식별하고 해당 WebElements에서 작업을 수행하는 페이지 메서드도 포함합니다. 이러한 메서드의 이름은 수행하는 작업에 따라 지정해야 합니다. 즉, 로더가 결제 게이트웨이가 나타날 때까지 기다리는 경우 POM 메서드 이름은 waitForPaymentScreenDisplay()가 될 수 있습니다.
왜 페이지 객체 모델인가?
UI 자동화 시작 Selenium WebDriver는 어려운 작업이 아닙니다. 요소를 찾고 작업을 수행하기만 하면 됩니다.
웹사이트에 로그인하려면 이 간단한 스크립트를 고려해 보세요.
보시다시피 우리가 하는 일은 요소를 찾고 해당 요소에 대한 값을 채우는 것뿐입니다.
이것은 작은 스크립트입니다. 스크립트 유지 관리가 쉬워 보입니다. 그러나 시간이 지나면 테스트 스위트가 커질 것입니다. 코드에 점점 더 많은 줄을 추가하면 상황이 어려워집니다.
스크립트 유지 관리의 가장 큰 문제는 10개의 서로 다른 스크립트가 동일한 페이지 요소를 사용하는 경우 해당 요소가 변경되면 10개의 스크립트를 모두 변경해야 한다는 것입니다. 이는 시간이 많이 걸리고 오류가 발생하기 쉽습니다.
스크립트 유지 관리에 대한 더 나은 접근 방식은 웹 요소를 찾고, 채우거나 확인하는 별도의 클래스 파일을 만드는 것입니다. 이 클래스는 해당 요소를 사용하는 모든 스크립트에서 재사용될 수 있습니다. 앞으로 웹 요소에 변경 사항이 있으면 1개의 다른 스크립트가 아닌 10개의 클래스 파일에서만 변경하면 됩니다.
이 접근 방식을 페이지 개체 모델이라고 합니다. Selenium. 이는 코드를 더 읽기 쉽고, 유지 관리하기 쉽고, 재사용하기 쉽게 만드는 데 도움이 됩니다.
POM의 장점
- 페이지 객체 디자인 패턴은 UI의 작업과 흐름을 검증과 분리해야 한다고 말합니다. 이 개념은 코드를 더 깔끔하고 이해하기 쉽게 만듭니다.
- 두 번째 이점은 개체 저장소가 테스트 사례와 독립적이므로 동일한 개체 저장소를 다른 도구를 사용하여 다른 목적으로 사용할 수 있다는 것입니다. 예를 들어 페이지 개체 모델을 다음과 같이 통합할 수 있습니다. Selenium 과 TestNG/JUnit 기능성 지원 동시에 JBehave/Cucumber 승인 테스트를 위해.
- POM 클래스의 재사용 가능한 페이지 메서드로 인해 코드가 줄어들고 최적화됩니다.
- 메서드에는 UI에서 발생하는 작업과 쉽게 매핑할 수 있는 더 현실적인 이름이 지정됩니다. 예를 들어, 버튼을 클릭한 후 홈페이지에 도달하면 메서드 이름은 'gotoHomePage()'와 같습니다.
POM을 구현하는 방법은 무엇입니까?
단순 POM:
모든 웹 요소가 페이지 개체 모델 프레임워크의 기본 구조입니다. AUT 그리고 이러한 웹 요소에서 작동하는 메서드는 클래스 파일 내부에서 관리됩니다. 검증과 같은 작업은 테스트 메서드의 일부로 분리되어야 합니다.
완전한 예
테스트케이스: Guru99 데모 사이트로 이동합니다.
1단계) Guru99 데모 사이트로 이동
2단계) 홈페이지에 "Guru99 Bank"라는 텍스트가 있는지 확인하세요.
3단계) 애플리케이션에 로그인하세요.
4단계) 홈 페이지에 "관리자 ID: 데모"라는 텍스트가 포함되어 있는지 확인합니다.
여기서 우리는 2페이지를 다루고 있습니다.
- 페이지 로그인
- 홈 페이지(로그인하면 표시됨)
따라서 우리는 2개의 POM을 생성합니다. Selenium 수업
Guru99 로그인 페이지 POM
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class Guru99Login { WebDriver driver; By user99GuruName = By.name("uid"); By password99Guru = By.name("password"); By titleText =By.className("barone"); By login = By.name("btnLogin"); public Guru99Login(WebDriver driver){ this.driver = driver; } //Set user name in textbox public void setUserName(String strUserName){ driver.findElement(user99GuruName).sendKeys(strUserName); } //Set password in password textbox public void setPassword(String strPassword){ driver.findElement(password99Guru).sendKeys(strPassword); } //Click on login button public void clickLogin(){ driver.findElement(login).click(); } //Get the title of Login Page public String getLoginTitle(){ return driver.findElement(titleText).getText(); } /** * This POM method will be exposed in test case to login in the application * @param strUserName * @param strPasword * @return */ public void loginToGuru99(String strUserName,String strPasword){ //Fill user name this.setUserName(strUserName); //Fill password this.setPassword(strPasword); //Click Login button this.clickLogin(); } }
Guru99 홈 페이지 POM in Selenium
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class Guru99HomePage { WebDriver driver; By homePageUserName = By.xpath("//table//tr[@class='heading3']"); public Guru99HomePage(WebDriver driver){ this.driver = driver; } //Get the User name from Home Page public String getHomePageDashboardUserName(){ return driver.findElement(homePageUserName).getText(); } }
Guru99 단순 POM Selenium 테스트 케이스
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 pages.Guru99HomePage; import pages.Guru99Login; public class Test99GuruLogin { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; Guru99Login objLogin; Guru99HomePage objHomePage; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("http://demo.guru99.com/V4/"); } /** * This test case will login in http://demo.guru99.com/V4/ * Verify login page title as guru99 bank * 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 Guru99Login(driver); //Verify login page title String loginPageTitle = objLogin.getLoginTitle(); Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank")); //login to application objLogin.loginToGuru99("mgr123", "mgr!23"); // go the next page objHomePage = new Guru99HomePage(driver); //Verify home page Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123")); }
페이지 팩토리란 무엇인가요? Selenium?
페이지 팩토리 Selenium 내장된 페이지 개체 모델 프레임워크 개념입니다. Selenium WebDriver는 매우 최적화되어 있습니다. Page 개체를 초기화하거나 Page 개체 자체를 인스턴스화하는 데 사용됩니다. 또한 "FindElement/s"를 사용하지 않고 페이지 클래스 요소를 초기화하는 데에도 사용됩니다.
여기에서도 페이지 개체 저장소와 테스트 방법을 분리하는 개념을 따릅니다. 또한 PageFactory 클래스의 도움으로 Selenium, 우리는 주석을 사용합니다 @FindBy WebElement를 찾으려면. initElements 메소드를 사용하여 웹 요소를 초기화합니다.
@FindBy 받아 들일 수있다 tagName, 부분 링크 텍스트, 이름, linkText, id, css, className, xpath 속성으로.
Page Factory를 사용하여 위와 동일한 예를 살펴보겠습니다.
Guru99 Page Factory 로그인 페이지
package PageFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class Guru99Login { /** * All WebElements are identified by @FindBy annotation */ WebDriver driver; @FindBy(name="uid") WebElement user99GuruName; @FindBy(name="password") WebElement password99Guru; @FindBy(className="barone") WebElement titleText; @FindBy(name="btnLogin") WebElement login; public Guru99Login(WebDriver driver){ this.driver = driver; //This initElements method will create all WebElements PageFactory.initElements(driver, this); } //Set user name in textbox public void setUserName(String strUserName){ user99GuruName.sendKeys(strUserName); } //Set password in password textbox public void setPassword(String strPassword){ password99Guru.sendKeys(strPassword); } //Click on login button public void clickLogin(){ login.click(); } //Get the title of Login Page public String getLoginTitle(){ return titleText.getText(); } /** * This POM method will be exposed in test case to login in the application * @param strUserName * @param strPasword * @return */ public void loginToGuru99(String strUserName,String strPasword){ //Fill user name this.setUserName(strUserName); //Fill password this.setPassword(strPasword); //Click Login button this.clickLogin(); } }
Page Factory가 포함된 Guru99 홈 페이지
package PageFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class Guru99HomePage { WebDriver driver; @FindBy(xpath="//table//tr[@class='heading3']") WebElement homePageUserName; public Guru99HomePage(WebDriver driver){ this.driver = driver; //This initElements method will create all WebElements PageFactory.initElements(driver, this); } //Get the User name from Home Page public String getHomePageDashboardUserName(){ return homePageUserName.getText(); } }
Page Factory 개념을 사용한 Guru99 TestCase
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.Guru99HomePage; import PageFactory.Guru99Login; public class Test99GuruLoginWithPageFactory { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; Guru99Login objLogin; Guru99HomePage objHomePage; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("http://demo.guru99.com/V4/"); } /** * This test go to http://demo.guru99.com/V4/ * Verify login page title as guru99 bank * 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 Guru99Login(driver); //Verify login page title String loginPageTitle = objLogin.getLoginTitle(); Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank")); //login to application objLogin.loginToGuru99("mgr123", "mgr!23"); // go the next page objHomePage = new Guru99HomePage(driver); //Verify home page Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123")); } }
전체 프로젝트 구조는 다이어그램과 같습니다.
AjaxElementLocatorFactory
AjaxElementLocatorFactory PageFactory의 지연 로딩 개념입니다. Selenium. 이는 요소가 모든 작업에서 사용될 때만 웹 요소를 찾는 데 사용됩니다. 이는 WebElements에 대한 시간 초과를 개체 페이지 클래스에 할당합니다. 패턴 PageFactory를 사용하는 주요 이점 중 하나는 Selenium AjaxElementLocatorFactory 클래스입니다.
여기서, 요소에 대한 작업이 수행되면 가시성을 기다리는 시간은 그 순간부터 시작됩니다. 주어진 시간 간격에서 요소를 찾을 수 없는 경우, 테스트 케이스 실행하면 'NoSuchElementException' 예외가 발생합니다.
요약
- 페이지 객체 모델 Selenium WebDriver는 개체 저장소 디자인 패턴입니다.
- Selenium 페이지 개체 모델은 유지 관리 및 재사용이 가능한 테스트 코드를 생성합니다.
- Page Factory는 Page Object Model 프레임워크 개념에서 개체 저장소를 생성하는 최적화된 방법입니다.
- AjaxElementLocatorFactory는 Page Factory의 지연 로드 개념으로, 모든 작업에서 WebElement가 사용될 때만 해당 요소를 식별하는 페이지 객체 디자인 패턴입니다.
를 다운로드 Selenium 이 튜토리얼의 데모용 프로젝트 파일