어제에 간단하게 예제를 살펴보았다. 이번에는 Fixture의 들어가는 인수 등을 살펴보자.
1. Autouse
autouse를 True로 설정하면, 별도 요청 없이 모든 테스트 함수에서 해당 fixture를 사용할 수 있다.
Sometimes you may want to have a fixture (or even several) that you know all your tests will depend on. “Autouse” fixtures are a convenient way to make all tests automatically request them. This can cut out a lot of redundant requests, and can even provide more advanced fixture usage (more on that further down).
다음과 같이 쓸 수 있다.
# contents of test_append.py
import pytest
@pytest.fixture
def first_entry():
return "a"
@pytest.fixture
def order(first_entry):
return []
@pytest.fixture(autouse=True)
def append_first(order, first_entry):
return order.append(first_entry)
def test_string_only(order, first_entry):
assert order == [first_entry]
def test_string_and_int(order, first_entry):
order.append(2)
assert order == [first_entry, 2]
append_first를 요청하지 않아도 테스트들은 모두 이에 영향을 받는다.
2. Scope
만약 fixture를 생성하는데 비용(시간)이 많이 걸린다면 scope 인자를 통해 fixture가 유지되는 범위를 지정할 수 있다.
예를 들어 네트워크 엑세스가 필요한 설비는 시간이 많이 걸린다. scope="module"로 설정하면 fixture가 모듈당 한 번만 호출되도록 할 수 있다.(기본값은 함수당 한 번 호출) 따라서 테스트 모듈의 여러 테스트 기능은 동일한 fixture를 사용하므로 시간이 절약된다.
다음 예제를 살펴보자.
# content of conftest.py
import smtplib
import pytest
@pytest.fixture(scope="module")
def smtp_connection():
return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
# content of test_module.py
def test_ehlo(smtp_connection):
response, msg = smtp_connection.ehlo()
assert response == 250
assert b"smtp.gmail.com" in msg
assert 0 # for demo purposes
def test_noop(smtp_connection):
response, msg = smtp_connection.noop()
assert response == 250
assert 0 # for demo purposes
여기서 test_ehlo에는 smtp_connection 고정장치 값이 필요하다. pytest가 @pytest를 발견하고 호출한다. smtp_connection fixture 함수로 표시된 테스트를 실행하는 방법은 다음과 같다.
$ pytest test_module.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
test_module.py FF [100%]
================================= FAILURES =================================
________________________________ test_ehlo _________________________________
smtp_connection = <smtplib.SMTP object at 0xdeadbeef0001>
def test_ehlo(smtp_connection):
response, msg = smtp_connection.ehlo()
assert response == 250
assert b"smtp.gmail.com" in msg
> assert 0 # for demo purposes
E assert 0
test_module.py:7: AssertionError
________________________________ test_noop _________________________________
smtp_connection = <smtplib.SMTP object at 0xdeadbeef0001>
def test_noop(smtp_connection):
response, msg = smtp_connection.noop()
assert response == 250
> assert 0 # for demo purposes
E assert 0
test_module.py:13: AssertionError
========================= short test summary info ==========================
FAILED test_module.py::test_ehlo - assert 0
FAILED test_module.py::test_noop - assert 0
============================ 2 failed in 0.12s =============================
해당 오류를 보면 동일한 인스턴스가 두 테스트 코드에 전달되었음을 확인 할 수 있다. 동일한 인스턴스를 재사용하기 때문에 단일 인스턴스만큼 빠르게 실행된다.
2.1 scope의 범위
Fixtures are created when first requested by a test, and are destroyed based on their scope:
- function: 기본 scope이다. 테스트 종료 시 파괴 된다.
- class: 클래스의 마지막 테스트를 해체하는 동안 파괴된다.
- module: 모듈의 마지막 테스트를 해체하는 동안 파괴된다.
- package: 패키지 범위
- session: 세션 범위
2.2 동적 스코프
fixture name을 문자열로 설정하고 구성 객체로 구성하는 두 개의 키워드 인수로 호출된다. 이것은 도커 컨테이너를 생성하는 것과 같이 설치 시간이 필요한 설비를 처리할 때 특히 유용할 수 있다. 명령행 인수를 사용하여 다른 환경에 대해 생성된 컨테이너의 범위를 제어할 수 있다.(이 부분은 다음에 좀 더 자세히 살펴보겠다.)
def determine_scope(fixture_name, config):
if config.getoption("--keep-containers", None):
return "session"
return "function"
@pytest.fixture(scope=determine_scope)
def docker_container():
yield spawn_container()
참고
https://docs.pytest.org/en/latest/how-to/fixtures.html#yield-fixtures-recommended
https://velog.io/@sangyeon217/pytest-fixture#scope-%EC%84%A4%EC%A0%95
'Python' 카테고리의 다른 글
결합과 추상화 - 2 (0) | 2023.02.13 |
---|---|
Pytest - 3. Monkeypatching functions (0) | 2023.02.03 |
Pytest 사용하기 - 1. 간단한 예제 (0) | 2023.01.31 |
파이썬으로 배우는 자료구조 핵심 원리 (0) | 2023.01.30 |
Python 3.10 변경점 알아보기 - 1. Parenthesized context managers, Better error messages (0) | 2023.01.28 |