
1. 서론: 왜 Fixture 스코프가 테스트의 성패를 결정하는가?
파이썬 생태계에서 pytest는 가장 강력한 테스트 프레임워크로 자리 잡았습니다. 그 중심에는 Fixture(픽스처)라는 개념이 존재합니다. 픽스처는 테스트를 실행하기 위한 '준비물' 혹은 '환경'을 의미하지만, 단순히 객체를 생성하는 것에 그치지 않습니다. 픽스처의 진정한 가치는 스코프(Scope) 디자인에 있습니다. 스코프를 잘못 설정하면 테스트 속도가 기하급수적으로 느려지거나, 테스트 간 상태 공유로 인해 'Flaky Test(때때로 실패하는 테스트)'가 발생합니다. 본 가이드에서는 Function부터 Session까지 4가지 스코프의 전략적 설계 패턴을 심층 분석합니다.
2. Pytest Fixture 스코프 핵심 비교
각 스코프는 데이터의 생명 주기와 공유 범위를 정의합니다. 이를 적재적소에 배치하는 것이 테스트 아키텍처의 핵심입니다.
| 스코프 명칭 | 생명 주기 (Lifetime) | 주요 용도 | 비용 (Cost) |
|---|---|---|---|
| Function | 각 테스트 함수 실행 시마다 생성/파괴 | 독립적인 데이터 모델, Mock 객체 | 매우 높음 (반복 생성) |
| Class | 클래스 내 모든 테스트 시작 전 1회 생성 | 공통된 클래스 단위 설정 (UI 테스트 등) | 중간 |
| Module | 파이썬 파일(.py) 단위로 1회 생성 | 데이터베이스 연결, 무거운 설정 파일 로드 | 낮음 |
| Session | 전체 테스트 프로세스 중 딱 1회 생성 | 외부 API 클라이언트 구축, 전역 캐시 | 매우 낮음 (최고 효율) |
3. 스코프별 디자인 패턴 및 실전 예제
3.1. Function 스코프: 엄격한 격리
기본값인 Function 스코프는 각 테스트가 서로 영향을 주지 않아야 하는 비즈니스 로직 검증에 최적입니다.
import pytest
@pytest.fixture(scope="function")
def user_profile():
# 매 테스트마다 새로운 유저 객체 생성
return {"id": 1, "name": "Chaewon", "points": 100}
def test_add_points(user_profile):
user_profile["points"] += 50
assert user_profile["points"] == 150
def test_reset_points(user_profile):
# 이전 테스트의 수정 사항이 반영되지 않음 (격리 성공)
assert user_profile["points"] == 100
3.2. Session 스코프: 전역 자원의 효율적 관리
데이터베이스 연결이나 Docker 컨테이너 생성과 같이 비용이 매우 큰 작업은 Session 스코프를 사용해야 합니다. conftest.py 파일에 정의하여 프로젝트 전역에서 공유하는 것이 일반적입니다.
@pytest.fixture(scope="session")
def db_connection():
# 수 초가 걸리는 DB 연결 작업을 단 1회만 수행
conn = database.connect("test_db")
yield conn
conn.close()
4. 전문적인 테스트 설계 전략: 'Tear-down'과 'Yield'
숙련된 개발자는 픽스처의 스코프를 정할 때 Cleanup(정리 작업)을 반드시 고려합니다. yield 키워드를 사용하면 테스트가 끝난 후 스코프의 수명이 다하는 시점에 리소스를 안전하게 반환할 수 있습니다.
"스코프가 넓을수록(Session 쪽으로 갈수록) 성능은 좋아지지만, 부작용(Side Effect) 관리가 까다로워집니다. Read-only 데이터는 Session으로, Write가 발생하는 데이터는 Function으로 설계하는 것이 정석입니다."
5. 결론: 최적의 스코프 선택을 위한 체크리스트
- 데이터가 테스트 중 수정되는가? (그렇다면 Function)
- 리소스 생성에 1초 이상의 시간이 소요되는가? (그렇다면 Module 이상)
- 프로젝트 전역에서 읽기 전용으로 쓰이는가? (그렇다면 Session)
- 동일한 클래스 내에서 환경을 공유해도 무방한가? (그렇다면 Class)
이러한 원칙을 바탕으로 픽스처를 설계하면, 코드의 품질은 물론 전체 CI/CD 파이프라인의 속도를 혁신적으로 개선할 수 있습니다.
'Artificial Intelligence > 60. Python' 카테고리의 다른 글
| [PYTHON] TDD를 넘어선 Property-based Testing : Hypothesis 라이브러리 심층 가이드 (0) | 2026.02.20 |
|---|---|
| [PYTHON] Mock 객체 사용 시 spec=True 옵션이 중요한 이유 : 깨지지 않는 테스트를 위한 방어적 설계 (0) | 2026.02.20 |
| [PYTHON] 대용량 CSV/JSON 파싱 시 Generator와 Stream 처리의 성능 및 메모리 효율성 비교 분석 (0) | 2026.02.20 |
| [PYTHON] __builtins__ 직접 참조를 통한 전역 조회 오버헤드 최적화 기법 (0) | 2026.02.20 |
| [PYTHON] cProfile 결과를 분석하여 병목 지점을 찾는 워크플로우 (0) | 2026.02.20 |