UI 테스트 자동화 프레임워크: Python Selenium 기반 설계 및 구현
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
웹 개발
대상자
- 소프트웨어 개발자, QA 엔지니어
- 인터미디트 이상의 Python/Selenium/Pytest 경험자
- 테스트 자동화 프레임워크 설계 및 구현에 관심 있는 개발자
핵심 요약
- 안정성 우선 원칙 :
SeleniumWrapper
클래스를 통해 명시적 대기(explicit waits)와 강력한 오류 처리(error handling)를 적용하여 테스트의 안정성을 확보 - 유지보수성 강화 : Page Object Model(POM) 패턴을 기반으로 한 모듈화된 테스트 구조로 테스트 코드의 재사용성과 유지보수성을 극대화
- 가독성 중심 설계 :
@allure
및Pytest
활용한 테스트 스크립트의 자연어 기반 표현으로 비기술자도 테스트 로직을 쉽게 이해 가능
섹션별 세부 요약
1. 프레임워크 설계 원칙
- 안정성 우선 : 테스트 속도보다 결과의 일관성을 중시
- 유지보수성 강조 : 테스트 코드를 생산 코드 수준의 품질로 관리
- 가독성 확보 : 테스트 스크립트가 수동 테스트 시나리오와 유사한 형식으로 작성
2. 프레임워크 아키텍처
ui-test-automation/
├── base/ # SeleniumWrapper, WebDriver 팩토리
├── pages/ # Page Object Model 구현
├── tests/ # Pytest 테스트 스크립트
├── testdata/ # 환경 설정 및 테스트 데이터
└── utils/ # 로깅, 리포트 등 유틸리티
base/
: 브라우저 상호작용 기능 제공pages/
: POM 패턴을 통해 페이지별 로케이터/액션 추상화utils/
:SeleniumWrapper
클래스로 명시적 대기(explicit wait) 기능 통합
3. Page Object Model 구현 예시
class ElementsPage(DemoQABase):
HEADER_LINK = ("css", "div#app a[href='Header Link']")
TEXT_BOX_MENU = ("xpath", "//span[contains(text(), 'Text Box')]", "Elements Card")
def is_at(self):
return self.is_element_present(self.TEXT_BOX_MENU)
- 로케이터 중복 제거 : UI 요소 변경 시 단일 위치에서 수정 가능
- 테스트와 로직 분리 : 테스트 스크립트는
what
을,pages/
는how
를 담당
4. SeleniumWrapper 기능
def click(self, locator_full, timeout=None):
timeout = timeout if timeout is not None else self.timeout
element = self.explicitly_wait(locator_full, timeout)
if not element:
self.log.error(f"Element not available: {locator_full[2]}")
return
try:
element.click()
self.log.info(f"Clicked element: {locator_full[2]}")
except StaleElementReferenceException:
self.log.error(f"Element became stale: {locator_full[2]}")
- 자동 복구 기능 :
StaleElementReferenceException
처리로 불안정한 요소 대응 - 로깅 강화 : 모든 액션에 대한 상세 로그 출력
5. 환경 설정 시스템
TEST_RUN_ON_SERVER
플래그로 로컬/서버 설정 자동 전환- AWS Parameter Store와 연동하여 보안 데이터 분리
base/
,local/
,secrets/
구성 파일을 통해 환경별 설정 병합
결론
- POM 패턴과 SeleniumWrapper를 통해 안정적이고 유지보수가 쉬운 테스트 자동화 프레임워크 구축 가능
GitHub
에서 프레임워크 클론 후 직접 실행하여 실무 적용 검증 권장- 테스트 스크립트의 가독성을 위해
@allure
및 자연어 기반 메서드 사용 필수