Page Object Model?
- 웹 애플리케이션 테스트 자동화를 위한 소프트웨어 디자인 패턴
POM 의 장점
- 재사용성 : 페이지의 각 요소가 객체로 모델링되어, 테스트 스크립트에서 반복적으로 사용 가능
- 유지보수성 : 페이지의 변경이 발생해도, 해당 페이지 객체만 업데이트하면 되므로 유지보수 용이
- 테스트 스크립트와 분리 : 페이지 객체와 Selenium 스크립트가 분리되어 코드 가독성 및 유지보수성 향상
- 테스트 코드 가독성 향상 : 스크립트 양이 많아져도 페이지의 역할이 뚜렷하므로 테스트 코드 이해가 쉬움
Directory Structure
# Example
Root
ㄴ base
ㄴ BasePage.py
ㄴ config
ㄴ Config.py
ㄴ pages
ㄴ LoginPage.py
ㄴ FindEmailPage.py
ㄴ FindPasswordPage.py
ㄴ MainPage.py
ㄴ ...
ㄴ utilities
ㄴ .github
ㄴ venv
ㄴ ...
base?
- Selenium 메서드를 활용한 커스텀 메서드의 집합 클래스 구성
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class BasePage:
def __init__(self, driver):
self.driver=driver
def wait_element_presence(self, selector, locator):
try:
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((selector, locator))
)
except TimeoutException:
print(f"{locator}" 10초 내에 찾지 못함)
def wait_element_clickable(self, selector, locator):
try:
WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((selector, locator))
)
except TimeoutException:
print(f"{locator}" 10초 내에 찾지 못함)
def is_displayed(self, selector, locator):
self.wait_element_presence(selector, locator)
element = self.driver.find_element(by=selector, value=locator)
element.is_displayed()
def click_element(self, selector, locator):
self.wait_element_clickable(selector, locator)
element = self.driver.find_element(by=selector, value=locator)
element.click()
def input_element(self, selector, locator, text):
self.wait_element_presence(selector, locator)
element = self.driver.find_element(by=selector, value=locator)
element.send_keys(text)
Config?
- 웹 페이지 테스트 데이터 구성
- 주로 계정 정보, URL, API 토큰 정보 등 포함 (민감한 정보)
BASE_URL = "https://velog.io/"
ID = "test@test.com"
PASSWORD = "Password1234!"
PageElements?
- 웹 페이지 XPATH 등 셀렉터 값에 대한 정보 구성
- pages 디렉토리에 포함시킴
id_input_field = '//*[@placeholder="Email"]'
password_input_field = '//*[@placeholder="Password"]'
login_button = '//button[@class="loginbtn"]'
pages?
- 웹 페이지에 대한 Selenium 스크립트 메서드 집합 클래스 구성
- BasePage 클래스를 상속받음
- BasePage 클래스에 정의된 커스텀 메서드를 사용하여 웹 페이지 테스트 스크립트 작성
- config.py 에서 필요한 변수(테스트 데이터)를 가져다 씀
- PageElements.py 에서 필요한 locator 값을 가져다 씀
from base.BasePage import BasePage
import pages.PageElements as elems
import config.Config as config
class LoginPage(BasePage):
def __init__(self, driver):
super().__init__(driver)
self.driver=driver
def input_id(self, text):
BasePage.input_element(self, elems.id_input_field, config.ID)
def input_password(self, text):
BasePage.input_element(self, elems.password_input_field, config.PASSWORD)
def click_login_button(self):
BasePage.click_element(self, elems.login_button)