Page Object Model 은 로케이터, 테스트 케이스, 테스트 스위트 등을 별도 파일로 모듈화해 관리하는 디자인 패턴이다
Page Object Model은 코드의 중복을 줄이고 테스트 케이스를 유지 보수하는 데 매우 효율적이다.
예를 들어 로그인 페이지의 Element 하나가 수정되었다고 가정하면 수정된 Element를 사용하는 모든 테스트 케이스를 하나하나 수정해야 할 것이다. 하지만 이 Element를 모듈화된 하나의 파일에서 관리하고 있다면 하나의 파일만 수정하면 간단히 유지 보수할 수 있게 된다.
이렇듯 손쉬운 유지보수와 코드의 재사용성, 코드의 가독성과 신뢰성 확보를 위하여 POM 패턴을 활용하는 것이 좋다.
├── Config # 공통으로 사용하는 정보들이 담긴 폴더 (계정 정보 등)
│ ├── __init__.py
│ └── config.py
├── Pages # Locator 와 page object들이 담긴 폴더
│ ├── __init__.py
│ ├── page_Base.py
│ └── page_splash.py
├── TestBase
│ ├── WebDriverSetup.py # WebDriver 셋팅 모듈이 담긴 폴더
│ ├── __init__.py
├── Tests # 테스트 케이스가 담긴 폴더
│ ├── TEST_BASIC
│ │ ├── BASIC_login.py
│ │ ├── __init__.py
│ ├── __init__.py
모든 페이지에서 공통으로 사용할 메서드는 page_Base.py
에 정의한다. 각 페이지에서 특별하게 사용하는 기능들은 해당 페이지 모듈에서 메서드로 만들어 사용한다.
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 click(self, by_locator):
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(by_locator)).click()
# 엘러먼트에 키 입력
def send_keys(self, by_locator, text):
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(by_locator)).send_keys(text)
Inspector 에서 알아낸 정보들을 토대로 locator 를 정의한다
아래 생성된 page_splash.py
는 앱 최초 실행 후 노출되는 스플래시 페이지의 locator 를 식별하여 정의한 것이다
from .page_Base import BasePage
from appium.webdriver.common.mobileby import MobileBy
class SplashPage(BasePage):
""" 앱 최초 실행 후 스플래시 페이지의 Locator """
btn_positive = (MobileBy.ID, "com.mrt.ducati.dev:id/btn_positive")
테스트 케이스 어디에서도 Locator를 정의하지 않았다.
from TestBase.WebDriverSetup import WebDriverSetup
from Pages.page_splash import SplashPage
class LoginTest:
def setUp(self):
""" 본 예제에서는 생략 """
def test_case_1(self):
""" 테스트 케이스 작성 """
splash = SplashPage(self.driver)
splash.click(SplashPage.btn_positive)
def tearDown(self):
""" 본 예제에서는 생략 """
최근 자동화를 시작한 초보입니다. 다름이아니라 unittest 정도 까지 공부를 하다 POM 을 적용하면 좋다하여 찾아보다 들리게되었습니다. 혹시 init.py 파일에는 어떤 내용들이 들어가는지 질문드립니다. 그리고 본예제에 생략된 코드가 무엇이 들어갈지 알려주시면 감사하겠습니다 ㅠㅠ