TDD - Pytest fixture 활용

정태경·2022년 4월 9일
0

TDD

목록 보기
5/10
post-thumbnail

Pytest의 아주 강력한 기능은 바로 fixture 기능이다. 간략하게 정리해 보자면 fixture는 테스트에 필요한 공통 자원들 또는 조건들을 미리 정의해둔 코드들이다. 이렇게 구현된 fixture는 필요에 따라 테스트 케이스마다 쉽게 가져와 사용할 수 있다. 일종의 디펜던시 인젝션 형태라고 이해하면 좋을듯하다.

fixture 정의와 활용

fixture는 @pytest.fixture 데코레이터를 통해 정의할 수 있다. 또한 fixture는 conftest.py에 정의해두면 모든 테스트 스위트에서 공통적으로 가져와 사용할 수 있다. 아래 코드는 fixture를 정의하는 예제 코드이다.

# conftest.py
@pytest.fixture
def set_userinfo():
	""" username과 password를 리턴해주는 fixture """
    username = "taekyeong@abcdefg.com"
    password = "abcdefg1234"
    return username, password

아래 코드는 사전에 정의된 set_userinfo fixture를 사용하는 예제 코드이다. 테스트할 메서드의 인자로 fixture를 넘겨주면 된다.

import pytest


class TestSignIn:

    def test_pytest(self, set_userinfo): 
        print(set_userinfo)
        
# 결과 : ("taekyeong@abcdefg.com", ("abcdefg1234"))

fixture Scope

fixture는 실행되는 범위에 대해 정의할 수 있다. fixture는 설정한 scope 단위로 실행되며 총 5단계의 scope가 존재한다.
function(default) < class < module < package < session

@pytest.fixture(scope="function") : 함수 단위로 1회 실행 (이 값은 디폴트 값이며 @pytest.fixture 와 동일함)
@pytest.fixture(scope="class")    : 클래스 단위로 1회 실행
@pytest.fixture(scope="module")   : 파일(py) 단위로 1회 실행
@pytest.fixture(scope="package")  : 패키지 단위로 1회 실행
@pytest.fixture(scope="session")  : test session동안 1회 실행

fixture parameterized

fixture param을 통해 같은 테스트를 여러 차례 실행할 수 있다. 아래 예제를 보면 테스트 코드는 test_pytest하나이지만 fixture param이 두 개 존재하여 총 2회의 테스트가 실행된 것을 알 수 있다.

@pytest.fixture(params=["abcd", "efgh"])
def first_fixture(request):
    param = request.param
    print(param)

def test_pytest(self, first_fixture):
        print("test_pytest 실행 완료")

""" 결과 : abcd
          test_pytest 실행 완료
          efgh
          test_pytest 실행 완료 """

fixture overriding

fixture도 오버라이딩이 가능하다. 아래 예제 코드를 살펴보자. conftest.pyset_username fixture가 존재하는 상태에서 TestSamlpe.py 모듈 안에 set_username을 오버라이딩 하였다. 이처럼 같은 모듈 내에 존재하는 fixture가 있다면 conftest.py 에 존재하는 fixture보다 높은 우선순위를 가진다.

# conftest.py
@pytest.fixture
def set_username():
    username = "taekyeong@abcdefg.com"
    password = "abcdefg1234"
    return username, password

# TestSamlpe.py
class TestSignIn:

    @pytest.fixture
    def set_username(self, set_username):
        username = "taekyeong@123123.com"      # 오버라이딩하여 username 재정의
        password = set_username[1]             # 부모 픽스쳐의 변수 그대로 사용 
        return username, password

    def test_pytest(self, set_username):
        print(set_username)


# 결과 : ('taekyeong@123123.com', 'abcdefg1234')
profile
現 두나무 업비트 QA 엔지니어, 前 마이리얼트립 TQA 엔지니어

0개의 댓글