본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] Pytest Fixture 스코프 디자인 패턴 : 효율적인 테스트 아키텍처 설계 가이드

by Papa Martino V 2026. 2. 20.
728x90

Pytest Fixture
Pytest Fixture

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. 결론: 최적의 스코프 선택을 위한 체크리스트

  1. 데이터가 테스트 중 수정되는가? (그렇다면 Function)
  2. 리소스 생성에 1초 이상의 시간이 소요되는가? (그렇다면 Module 이상)
  3. 프로젝트 전역에서 읽기 전용으로 쓰이는가? (그렇다면 Session)
  4. 동일한 클래스 내에서 환경을 공유해도 무방한가? (그렇다면 Class)

이러한 원칙을 바탕으로 픽스처를 설계하면, 코드의 품질은 물론 전체 CI/CD 파이프라인의 속도를 혁신적으로 개선할 수 있습니다.


내용의 출처 및 참고 문헌

  • Pytest Official Documentation: "About fixtures - Scope"
  • Python Testing with pytest (2nd Edition) by Brian Okken
  • Test-Driven Development with Python by Harry Percival
728x90