Selenium 또는 Appium을 통해 UI 자동화를 구현할 때 가장 많이 사용되는 디자인 패턴은 Page Object Model과 Page Object Factory이다.
두 방식 모두 각 페이지별 객체를 만들어 유지보수 용이성을 확보하고 코드 가독성을 높일 수 있는 설계 방법인데 실제 코드 상에서는 어떤 차이점이 있는지 알아보자.
먼저 Page Object Model을 적용한 코드를 살펴보자.
By
라는 데이터타입의 변수에 엘리먼트를 정의하고 있으며 driver.findElement()
메서드를 활용하여 엘리먼트를 리턴하고 있다.
package PageRepository;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class Loginpage {
WebDriver driver;
public Loginpage(WebDriver driver) {
this.driver = driver;
}
// 엘리먼트 정의
By btnEmail = By.xpath("//span[text()='이메일']");
By btnKakao = By.xpath("//span[text()='카카오']");
// 엘리먼트 리턴
public WebElement btnEmail() {
return driver.findElement(btnEmail);
}
// 엘리먼트 리턴
public WebElement btnKakao() {
return driver.findElement(btnKakao);
}
}
이번엔 Page Object Factory를 적용한 코드를 살펴보자.
@FindBy
어노테이션을 활용하여 WebElement
데이터 타입의 엘리먼트를 정의하고 있으며 driver.findElement()
메서드를 전혀 사용하고 있지 않다. 이처럼 Page Object Factorys는 POM보다 더 단순하고 가독성이 높은 코드를 작성할 수 있게 해준다는 장점이 있다.
package PageRepository;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class Loginpage {
WebDriver driver;
public Loginpage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
// 엘리먼트 정의
@FindBy(xpath = "//span[text()='이메일']")
WebElement btnEmail;
@FindBy(xpath = "//span[text()='카카오']")
WebElement btnKakao;
// 엘리먼트 리턴
public WebElement btnEmail() {
return btnEmail;
}
// 엘리먼트 리턴
public WebElement btnKakao() {
return btnKakao;
}
}
아직은 자동화 시장에서 Page Object Model(POM)이 더 많이 사용되는 듯하지만, Page Object Factory도 장점이 많은 구현 방식이라 알아두면 좋을 것 같다.