:: python

python :: 파이썬 테스트(unit test) 코드 작성 라이브러리 pytest 와 fixture

토람이 2022. 2. 3. 22:34

코드 작성 후 코드가 정상적으로 동작하는지 확인하기 위해 테스트 파일을 작성한다.
파이썬에서는 테스트 파일 작성 시 pytest 를 많이 사용하는데,

이 pytest 는 fixture 라는 유용한 기능을 제공한다.

 

 

fixture 는 선언한 함수를 테스트 함수에서 인자로 받아 사용할 수 있게 해주는 기능이다.
1) 테스트 함수 A를 작성하고

2) A에 fixture 를 선언하면,

3) 다른 테스트 함수에서 A의 결과를 받아와 사용할 수 있다.


이런 특징은 테스트 함수 작성 시 아주 유용한데,

fixture 가 어떻게 활용되는지 알아보자.

 

1. fixture 사용법

먼저 fixture 를 사용하는 방법은 간단하다.

pytest 를 import 한 후, 대상 함수 위에 다음과 같이 정의하면 된다.

import pytest

@pytest.fixture
def test():
    return 0

 

2. fixture 특징

간단한 예를 들어보자.

여러 개의 테스트 함수에서 같은 데이터를 사용한다면 데이터를 fixture 로 정의할 수 있다.

 

- fixture 사용 전

def test1():
    data = ['This', 'is', 'a', 'test', '.']
    result = " ".join(data)
    assert result == "This is a test ."

def test2():
    data = ['This', 'is', 'a', 'test', '.']
    result = "".join(data)
    assert result == "Thisisatest."

 

 

- fixture 사용 후

@pytest.fixture
def data():
    a = ['This', 'is', 'a', 'test', '.']
    return a

def test1(data):
    result = " ".join(data)
    assert result == "This is a test ."

def test2(data):
    result = "".join(data)
    assert result == "Thisisatest."


* test1: 입력받은 단어들을 공백을 붙여서 합침

* test2: 입력받은 단어들을 공백 없이 합침

 

 

위 예시를 통해 알 수 있는 fixture 의 특징은 다음과 같다.

 

 

1) 테스트 코드 내 중복코드를 줄여 간결하게 만들 수 있다.

위 예시는 중복코드가 많지 않지만, 중복코드가 길수록 더욱 눈에 띄는 특징이다.
동일하게 반복되는 코드를 하나의 함수로 빼서 fixture 를 선언하고,
다른 함수에서는 이 함수명인자로 받아와서 사용할 수 있다.

 


2) 여러 번 사용(호출)할 수 있다.

test3, test4, ... 등 테스트 함수를 추가로 선언하여

원할 때 언제든 data 를 인자로 불러올 수 있다.

즉, fixture 로 선언된 함수는 reusable 하다.

 

 

3) fixture 는 다른 fixture 를 호출할 수도 있다.

@pytest.fixture
def first_entry():
    return "a"

@pytest.fixture
def order(first_entry):
    return [first_entry]

def test_string(order):
    order.append("b")
    assert order == ["a", "b"]

 

위 예시처럼 테스트 함수를 기능별로 나누어 모듈화하여 호출하는 것이 가능해진다.

 


4) 한 번에 여러 fixture 를 호출할 수도 있다.

@pytest.fixture
def first_entry():
    return 1

@pytest.fixture
def second_entry():
    return 2

def test(first_entry, second_entry):
    assert (first_entry + second_entry) == 3

 

위 예시처럼 fixture 로 선언된 여러 개의 함수를 한꺼번에 인자로 받아와 각각 사용할 수 있다.

 

 

3. fixture 옵션

1) autouse

@pytest.fixture(autouse=True)

 

autouse=True 이면 해당 함수는 무조건 자동으로 실행된다.
해당 함수를 호출하는 함수가 있든 없든 상관 없다.

 

 

2) scope

@pytest.fixture(scope="module")

 

fixture 함수가 한 번 실행된 후 유효할(지속될) 범위를 지정한다.

 

원하는 범위에 따라 scope 는 다음과 같은 단계들로 지정 가능하다.

 

function the default scope, the fixture is destroyed at the end of the test.
class the fixture is destroyed during teardown of the last test in the class.
module the fixture is destroyed during teardown of the last test in the module.
package the fixture is destroyed during teardown of the last test in the package.
session the fixture is destroyed at the end of the test session.

 

 

4. yield

fixture 선언 함수는 return 을 통해 결과물을 다른 함수에 전달할 수 있는데,

테스트 실행 후에 데이터를 정리할 목적으로 return 대신 yield 를 사용할 수 있다.


fixture 함수 안에서 yield 문 뒤에 코드를 더 작성해두면
테스트가 끝난 후 이 yield문 뒤의 코드들이 실행된다.

그래서 yield 문 뒤에는 보통 teardown code 라고 하는, 

테스트 환경과 데이터를 정리하는 용도의 코드가 들어가게 된다.

 

yield 문을 활용한 다음 예시를 보자.

from selenium.webdriver import Chrome

@pytest.fixture
def driver():
    driver = Chrome()
    yield driver

    driver.quit()

 

driver 를 사용한 테스트 코드가 종료된 후

driver.quit() 이 실행되어 연결을 끊고 종료할 수 있게 해준다.

300x250