파이썬 Selenium 중급 가이드 pytest 픽스처와 드라이버 팩토리 세션 스코프 활용법
🚀 테스트 자동화를 한층 업그레이드하는 Selenium과 pytest 실전 팁 공개
테스트 자동화를 처음 시작할 때는 단순한 코드 실행만으로도 만족할 수 있습니다.
하지만 프로젝트가 커지고 테스트 케이스가 많아질수록, 효율적인 관리와 재사용 가능한 구조가 필요해집니다.
특히 Selenium을 이용한 브라우저 자동화에서는 실행 환경, 드라이버 생성, 세션 스코프 관리가 제대로 갖춰지지 않으면 유지보수가 힘들어지죠.
많은 개발자들이 pytest와 함께 Selenium 픽스처, 드라이버 팩토리, 세션 스코프 전략을 활용해 문제를 해결하고 있습니다.
이번 글에서는 이런 중급 수준의 핵심 개념과 실전 적용 방법을 차근차근 소개해 드립니다.
단순히 기능을 실행하는 수준을 넘어서, 테스트 코드의 구조화와 효율적인 리소스 관리를 고민하고 있다면 이 글이 큰 도움이 될 것입니다.
여기서는 pytest의 픽스처를 통해 Selenium 드라이버를 더 깔끔하게 구성하는 방법, 드라이버 팩토리를 활용해 다양한 브라우저 테스트를 유연하게 설정하는 방법, 그리고 세션 스코프를 통해 반복 실행 시간을 줄이는 노하우까지 실제 프로젝트에 바로 적용할 수 있는 전략을 다룹니다.
📋 목차
🧩 pytest와 Selenium 픽스처 이해하기
테스트 자동화에서 pytest가 널리 사용되는 이유 중 하나는 픽스처(fixture) 기능 덕분입니다.
픽스처는 테스트 실행 전후에 필요한 준비와 정리 과정을 자동화해 주어, 코드 중복을 줄이고 유지보수성을 높여 줍니다.
특히 Selenium과 함께 사용할 때는 브라우저 드라이버를 효율적으로 생성하고 종료하는 데 핵심적인 역할을 합니다.
예를 들어, 단일 테스트마다 드라이버를 새로 열고 닫는 방식은 테스트가 많아질수록 실행 시간이 길어지고 리소스를 많이 소모하게 됩니다.
반면 pytest의 픽스처를 활용하면 드라이버 인스턴스를 공통으로 관리하거나, 특정 스코프(함수, 클래스, 모듈, 세션)에 맞춰 재사용할 수 있습니다.
이를 통해 테스트 실행 시간을 단축하고 안정성을 높일 수 있습니다.
⚡ 함수 스코프와 클래스 스코프의 차이
픽스처는 스코프(scope)라는 개념을 통해 활용됩니다.
함수 스코프는 각 테스트 함수마다 새로운 드라이버를 생성하는 방식으로, 테스트 독립성을 보장하지만 실행 속도는 상대적으로 느려질 수 있습니다.
클래스 스코프는 테스트 클래스 내에서 동일한 드라이버 인스턴스를 공유하기 때문에 속도가 빨라지지만, 테스트 간 상호 의존성이 생길 수 있다는 단점이 있습니다.
import pytest
from selenium import webdriver
@pytest.fixture(scope="function")
def driver():
driver = webdriver.Chrome()
yield driver
driver.quit()
위 예시에서 함수 스코프를 사용하면 각 테스트 실행마다 크롬 드라이버가 열리고 닫히게 됩니다.
이 방식은 독립적인 테스트 실행에 유리합니다.
하지만 테스트 수가 많아지면 실행 시간이 크게 늘어나므로, 클래스 스코프나 세션 스코프 활용을 검토하는 것이 좋습니다.
💎 핵심 포인트:
pytest의 픽스처는 Selenium 테스트의 반복되는 준비와 정리 과정을 단순화하는 핵심 도구입니다. 적절한 스코프 설정은 실행 속도와 안정성에 직접적인 영향을 줍니다.
⚙️ 드라이버 팩토리 패턴으로 브라우저 관리
실무에서는 다양한 브라우저 환경에서 동일한 테스트를 실행해야 하는 경우가 많습니다.
크롬, 파이어폭스, 엣지 등 여러 브라우저를 동시에 관리하려면 드라이버 생성 로직을 일일이 테스트 코드에 작성하는 것은 비효율적입니다.
이때 유용하게 쓰이는 것이 드라이버 팩토리(driver factory) 패턴입니다.
드라이버 팩토리는 브라우저별 드라이버 생성을 하나의 함수나 클래스에서 통합 관리할 수 있게 해줍니다.
즉, 테스트 코드에서는 단순히 “브라우저 이름”만 지정하면 알아서 해당 드라이버를 실행시켜 주는 방식입니다.
이런 구조를 갖추면 크로스 브라우징 테스트가 훨씬 유연해지고, 새 브라우저 환경을 추가할 때도 코드 수정이 최소화됩니다.
🖥️ 드라이버 팩토리 구현 예시
from selenium import webdriver
def get_driver(browser="chrome"):
if browser == "chrome":
return webdriver.Chrome()
elif browser == "firefox":
return webdriver.Firefox()
elif browser == "edge":
return webdriver.Edge()
else:
raise ValueError(f"지원하지 않는 브라우저: {browser}")
위의 예시처럼 드라이버 팩토리를 구성하면 테스트 코드에서는 단순히 get_driver("firefox") 같은 호출만으로 다양한 브라우저를 실행할 수 있습니다.
이 방식은 코드 중복을 제거하고, 유지보수를 훨씬 쉽게 만들어 줍니다.
- 🛠️브라우저 추가 시 팩토리 함수만 수정하면 됨
- ⚡크로스 브라우징 테스트 환경을 유연하게 확장 가능
- 🚀테스트 코드에서 드라이버 생성 로직 분리로 가독성 향상
💡 TIP: CI/CD 환경에서는 환경 변수로 브라우저 이름을 지정해 드라이버 팩토리와 연동하면, 빌드 파이프라인에서 손쉽게 멀티 브라우저 테스트를 실행할 수 있습니다.
📂 세션 스코프와 테스트 실행 최적화
테스트 실행 시간이 길어지는 주요 원인 중 하나는 각 테스트마다 브라우저 드라이버를 반복적으로 실행하는 것입니다.
이런 상황에서는 pytest의 세션 스코프(session scope)를 활용하면 큰 개선을 얻을 수 있습니다.
세션 스코프는 테스트 세션 전체에서 한 번만 드라이버를 생성하고, 모든 테스트에서 이를 공유하도록 합니다.
예를 들어 100개의 테스트가 있다고 가정해봅시다.
함수 스코프를 사용하면 드라이버가 100번 열리고 닫히지만, 세션 스코프를 사용하면 단 한 번만 열리므로 실행 속도가 획기적으로 개선됩니다.
물론 테스트 간 상태가 공유되기 때문에, 독립성을 해치지 않도록 주의해야 합니다.
🧪 세션 스코프 픽스처 예시
import pytest
from selenium import webdriver
@pytest.fixture(scope="session")
def driver():
driver = webdriver.Chrome()
yield driver
driver.quit()
이 코드에서는 테스트 세션이 시작될 때 크롬 드라이버가 한 번 실행되고, 모든 테스트가 종료된 뒤에만 닫히게 됩니다.
이 방식은 대규모 테스트 환경에서 시간을 크게 절약할 수 있습니다.
💬 세션 스코프는 실행 시간을 단축하는 데 효과적이지만, 상태 공유로 인해 특정 테스트가 다른 테스트에 영향을 줄 수 있습니다. 독립성이 중요한 경우에는 모듈 스코프나 클래스 스코프를 적절히 활용하는 것이 더 안전합니다.
⚠️ 주의: 세션 스코프는 브라우저 세션이 길게 유지되므로, 쿠키나 세션 스토리지 값이 누적될 수 있습니다. 이를 초기화하지 않으면 테스트 결과가 왜곡될 수 있습니다.
🛠️ 실무에서 활용되는 구성 예시
pytest와 Selenium을 함께 사용할 때는 단순한 예제 수준을 넘어서, 실제 프로젝트 환경에 맞는 구성이 필요합니다.
특히 여러 브라우저에서 테스트를 수행하고, 반복 실행 시간을 줄이며, 코드 재사용성을 높이는 것이 중요한 과제입니다.
실무에서는 이를 위해 드라이버 팩토리와 픽스처 스코프를 결합한 형태가 자주 사용됩니다.
🔧 conftest.py 활용
대부분의 프로젝트에서는 conftest.py 파일을 두어 픽스처와 드라이버 팩토리를 정의합니다.
이렇게 하면 테스트 코드가 훨씬 깔끔해지고, 공통 설정을 일괄적으로 관리할 수 있습니다.
# conftest.py
import pytest
from selenium import webdriver
def create_driver(browser="chrome"):
if browser == "chrome":
return webdriver.Chrome()
elif browser == "firefox":
return webdriver.Firefox()
else:
raise ValueError("지원하지 않는 브라우저")
@pytest.fixture(scope="session")
def driver(request):
browser = request.config.getoption("--browser")
driver = create_driver(browser)
yield driver
driver.quit()
def pytest_addoption(parser):
parser.addoption("--browser", action="store", default="chrome")
위 예시처럼 --browser 옵션을 pytest 실행 시 전달하면, 원하는 브라우저에서 테스트를 실행할 수 있습니다.
이 방식은 CI/CD 파이프라인과도 잘 맞아, 자동화된 빌드 환경에서 유연하게 활용할 수 있습니다.
| 구성 요소 | 설명 |
|---|---|
| 드라이버 팩토리 | 브라우저별 드라이버 생성 관리 |
| 픽스처 스코프 | 테스트 실행 단위별 드라이버 재사용 |
| pytest 옵션 | 실행 시 원하는 브라우저 선택 가능 |
💎 핵심 포인트:
실무에서는 conftest.py를 활용해 픽스처와 드라이버를 중앙집중식으로 관리하는 것이 효율적입니다. 이렇게 하면 테스트 코드가 간결해지고, 확장성이 크게 향상됩니다.
💡 유지보수성과 확장성을 높이는 팁
프로젝트가 커질수록 테스트 코드의 유지보수성과 확장성은 더욱 중요해집니다.
단순히 테스트가 동작하는 수준에서 멈추지 않고, 읽기 쉽고 관리하기 좋은 구조를 갖추는 것이 장기적으로 효율성을 높이는 핵심 전략입니다.
pytest와 Selenium을 조합할 때는 다음과 같은 팁들을 적용하면 안정적인 테스트 환경을 유지할 수 있습니다.
📌 유지보수성 향상을 위한 전략
- 📂Page Object Pattern을 적용해 UI 요소와 테스트 로직 분리
- 🔄테스트 실행 전후 데이터 초기화로 독립성 보장
- ⚡병렬 실행(pytest-xdist)을 통해 대규모 테스트 시간 단축
- 🔧브라우저 설정을 환경 변수나 설정 파일에서 관리
- 🧩공용 유틸리티 모듈을 작성해 중복 로직 제거
🚀 확장성을 고려한 CI/CD 파이프라인
지속적인 통합(CI)과 배포(CD) 환경에서 테스트 자동화를 적용하면, 코드 변경 시마다 품질을 빠르게 검증할 수 있습니다.
이 과정에서 드라이버 팩토리와 pytest 옵션을 활용하면 브라우저를 유연하게 지정할 수 있고, Docker 같은 컨테이너 환경을 통해 일관된 실행 환경을 유지할 수 있습니다.
💎 핵심 포인트:
코드 구조화, 데이터 초기화, 병렬 실행, 그리고 CI/CD 환경 적용은 장기적인 관점에서 테스트 자동화의 품질과 속도를 동시에 높여 줍니다.
❓ 자주 묻는 질문 (FAQ)
pytest에서 픽스처를 꼭 써야 하나요?
드라이버 팩토리는 어떤 상황에서 유용한가요?
세션 스코프를 쓰면 테스트가 더 빨라지나요?
Page Object Pattern은 꼭 필요한가요?
pytest-xdist를 사용하면 어떤 장점이 있나요?
CI/CD 파이프라인에서 Selenium 테스트를 돌릴 수 있나요?
세션 스코프를 쓰면 독립적인 테스트가 어려운가요?
pytest 옵션을 활용해 브라우저를 지정할 수 있나요?
--browser 옵션을 추가하면 크롬, 파이어폭스, 엣지 등 원하는 브라우저를 선택해 테스트할 수 있습니다.
📝 pytest와 Selenium 중급 활용 핵심 정리
pytest와 Selenium을 함께 활용하면 단순한 브라우저 자동화를 넘어, 대규모 프로젝트에서도 확장성과 유지보수성을 갖춘 테스트 환경을 만들 수 있습니다.
픽스처는 반복되는 드라이버 실행 로직을 간소화하고, 드라이버 팩토리는 다양한 브라우저 테스트를 손쉽게 지원하며, 세션 스코프는 실행 시간을 획기적으로 단축해 줍니다.
또한 Page Object Pattern, pytest-xdist 병렬 실행, CI/CD 파이프라인과의 연동 같은 전략을 더하면 더욱 완성도 높은 자동화 프레임워크를 구축할 수 있습니다.
테스트 자동화를 효율적으로 운영하고 싶은 개발자라면 이번에 다룬 방법들을 반드시 실무에 적용해 보길 권장합니다.
🏷️ 관련 태그 : Selenium, pytest, 파이썬테스트자동화, 드라이버팩토리, 세션스코프, 브라우저자동화, 테스트프레임워크, CI/CD, 병렬테스트, PageObjectPattern