본문으로 건너뛰기

[pytest] async fixture를 플러그인 없이 요청 시 hard error로 전환

PR 링크: pytest-dev/pytest#14015 상태: Merged | 변경: +93 / -117

들어가며

pytest 8.4에서 도입된 경고(PytestRemovedIn9Warning)는, async fixture를 처리할 플러그인(예: pytest-asyncio) 없이 동기 테스트에서 async fixture를 요청하면 발생했습니다. pytest 9.0에서 이 경고가 hard error로 격상되었습니다. async fixture가 동기 테스트에 전달되면 awaited되지 않은 coroutine이 그대로 전달되어 예측할 수 없는 동작이 발생하기 때문입니다.

핵심 코드 분석

경고에서 에러로 전환

Before (fixtures.py):

warnings.warn(
    PytestRemovedIn9Warning(
        f"{request.node.name!r} requested an async fixture "
        f"{request.fixturename!r}{auto_str}, with no plugin or hook that "
        "handled it. This is usually an error, as pytest does not natively "
        "support it. "
        "This will turn into an error in pytest 9.\n"
        "See: https://docs.pytest.org/en/stable/deprecations.html#sync-test-depending-on-async-fixture"
    ),
    stacklevel=1,
)

After:

fail(
    f"{request.node.name!r} requested an async fixture {request.fixturename!r}{auto_str}, "
    "with no plugin or hook that handled it. This is an error, as pytest does not natively support it.\n"
    "See: https://docs.pytest.org/en/stable/deprecations.html#sync-test-depending-on-async-fixture",
    pytrace=False,
)

warnings.warn() 대신 fail()을 호출하여, 테스트가 errors로 분류되고 즉시 중단됩니다. pytrace=False로 pytest 내부 스택 트레이스를 숨깁니다.

테스트 검증 변경

Before:

result = pytester.runpytest("-Wdefault::pytest.PytestRemovedIn9Warning")
result.assert_outcomes(passed=1, warnings=1)

After:

result = pytester.runpytest()
result.assert_outcomes(errors=1)

pytest-asyncio 통합 테스트 복원

# pytest.ini - 이전에 주석 처리됨
asyncio_mode = strict
# requirements.txt
pytest-asyncio==1.3.0  # 이전에 주석 처리됨

pytest 9 지원이 준비된 pytest-asyncio 버전으로 통합 테스트를 복원했습니다.

왜 이게 좋은가

  • 조용히 깨지는 테스트를 방지합니다. async fixture의 coroutine이 그대로 전달되면 assert coroutine_object가 항상 True가 되어 거짓 성공을 만듭니다.
  • fixture 캐싱으로 인한 비결정적 동작을 제거합니다. 상위 스코프에서 async 테스트가 먼저 실행되면 캐시된 값이 동기 테스트에 전달되어 "동작하는 것처럼" 보일 수 있었습니다.
  • 에러 메시지가 명확하여, 사용자가 pytest-asyncio 같은 플러그인을 설치하거나 동기 래퍼를 사용하도록 안내합니다.

정리

  • deprecation 경고는 약속한 시점에 에러로 전환하라: 충분한 마이그레이션 기간(8.4 → 9.0) 후에 경고를 에러로 격상하는 것은 올바른 관행입니다.
  • 비결정적 동작은 조기에 차단하라: 캐싱, 실행 순서 등에 따라 결과가 달라지는 코드는 명시적 에러로 막아야 합니다.

참고 자료

⚠️ 알림: 이 분석은 AI가 실제 코드 diff를 기반으로 작성했습니다.

댓글

관련 포스트

PR Analysis 의 다른글