코드로 우주평화
@pytest.fixture 로 test 데이터 세팅하기 본문
pytest.fixture 는 왜 사용할까?
테스트 코드를 작성하다보면 ‘클라이언트’나 ‘토큰’, ‘객체’ 등이 필요할 수 있습니다.
보통은 setup 이나 teardown 등으로 데이터를 세팅할 수 있지만 pytest에는 fixture 데코레이터를 통해 필요한 데이터를 세팅하고 어떤 테스트 함수든지 재활용할 수 있습니다.
테스트 코드 예시
아래는 로그인 api를 테스트 하는 함수입니다.
# test_login.py
def test_login_api(client, create_user):
data = {
"email": "test@test.com",
"password": "password",
}
r = client.post("/api/v1/login", json=data)
r_message = r.json()
assert r.status_code == 200
assert r_message.get("access_token")
assert r_message.get("refresh_token")
test_login_api함수는 ‘client’, ‘create_user’ 라는 두 개의 인자를 받고 있습니다.
client는 url요청에 필요한 것이고
create_user는 테스트 전에 생성된 유저를 뜻합니다.
(유저가 생성되어야 로그인을 할 수 있으므로)
실제 테스트를 돌려보니 성공했다는 메시지가 나옵니다.
============================================================================================= test session starts ==============================================================================================
platform darwin -- Python 3.10.0, pytest-7.1.1, pluggy-1.0.0
rootdir: /Users/daco/alphaprime/portfolio-toy-project-uckim
plugins: anyio-3.5.0
collecting ... SECRET_KEY
collected 1 item
ap_toy/tests/api/test_login.py . [100%]
============================================================================================== 1 passed in 0.35s ===============================================================================================
그런데 이상합니다.
위의 코드를 다시 살펴보면 import가 명시되어있지 않다는 것을 알 수 있습니다.
test_login_api 함수의 인자는 도대체 어디에서 온걸까요?
답은 @pytest.fixture
쉬운 이해를 위해 create_user의 경우만 살펴보겠습니다.
코드는 다음과 같습니다.
# conftest.py
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from .config import settings
from .models import User
db_engine = create_engine(settings.POSTGRES_DSN)
session = sessionmaker(autocommit=False, autoflush=False, bind=db_engine)
@pytest.fixture
def create_user():
user = User(
nickname="test",
email="test@test.com",
password="1q2w3e4r",
)
db = session()
db.add(user)
db.commit()
create_user 함수 위에 pytest.fixture 데코레이터가 작성된 것을 볼 수 있습니다.
@pytest.fixture
def create_user():
이제 이 함수는 테스트 함수에 인자로 넣을 수 있는 함수가 됩니다.
다시 테스트 코드로 돌아가 보면 인자로 create_user가 있는 것을 볼 수 있습니다.
# test_login.py
def test_login_api(client, create_user):
이렇게 들어간 create_user 함수는 해당 테스트 함수가 실행될 때 먼저 실행됩니다.
유저가 생성되었으니 이제 로그인 테스트를 정상적으로 수행할 수 있습니다.
마무리
@pytest.fixture를 사용하면 번거롭게 데이터 세팅을 여러번 할 필요가 없습니다.
한번 작성해두면 테스트 클래스나 모듈별로 setup, teardown을 작성하지 않아도 되므로 테스트를 좀 더 수월하게 작성할 수 있습니다.
이 외에도 데이터베이스를 생성하고 초기화하는 등의 일련의 과정을 @pytest.fixtur로 구현할 수 있습니다.
자세한 사용법은 공식문서를 참고하시기 바랍니다!
'나는 이렇게 학습한다 > Debug' 카테고리의 다른 글
SQLAlchemy _ NotSupportedError(InvalidCachedStatementError) 에러 해결 (0) | 2022.04.29 |
---|---|
컬럼 속성 변경 후 alembic migration할 때 ‘None’ 생기는 현상 (0) | 2022.04.26 |
pytest _ 하나의 함수에서 복수 케이스 테스트 하는 방법 (0) | 2022.04.20 |
내가 쓴 Python 테스트 코드 coverage 알아보기 (0) | 2022.03.20 |
[TIL]django__데이터 중복_IntegrityError_ValidationError (1) | 2021.11.21 |