pytest

pytest는 Python에서 가장 널리 사용되는 테스트 프레임워크 중 하나로, 유닛테스트, 통합테스트 등 다양한 테스트를 쉽고 유연하게 작성하고 실행할 수 있도록 도와줍니다. 이 패키지는 매우 직관적이고 간결한 문법으로 제공하여, 복잡한 테스트 코드를 단순하게 작성할 수 있습니다. pytest는 기본적으로 python의 내장 unittest 프레임워크보다 더 많은 기능과 유연성을 제공합니다.

주요 특징

  1. 간결한 테스트 함수: pytest는 클래스나 메서드 기반이 아닌, 단순한 함수로 테스트를 작성할 수 있습니다. 별도의 클래스나 setup, teardown 메서드를 작성할 필요 없이 간단한 함수로 테스트가 가능합니다.
def test_addition():
    assert 1+1 == 2
================================ test session starts =================================
platform linux -- Python 3.10.12, pytest-8.3.2, pluggy-1.5.0
rootdir: /data/dev/pytest
plugins: anyio-4.4.0
collected 1 item                                                                     

test_addition.py .                                                               [100%]

================================= 1 passed in 0.01s ==================================
  1. 확장성: pytest는 플러그인 시스템을 지원하여, 기본 기능을 확장할 수 있습니다. 예를 들어, pytest-cov 플러그인을 사용하면 코드 커버리지를 측정할 수 있고, pytest-django와 같은 플러그인은 Django와 함께 테스트를 쉽게 작성할 수 있도록 도와줍니다.

  2. 강력한 assertion 리포트: pytest는 테스트 실패 시 매우 읽기 쉬운 리포트를 제공해 디버깅을 쉽게 할 수 있습니다.

def test_failing():
    assert 1+1 == 3
================================================================ test session starts ================================================================
platform linux -- Python 3.10.12, pytest-8.3.2, pluggy-1.5.0
rootdir: /data/dev/pytest
plugins: anyio-4.4.0
collected 3 items                                                                                                                                   

test_failing.py F                                                                                                                             [ 33%]
test_fixture.py .                                                                                                                             [ 66%]
test_sample.py .                                                                                                                              [100%]

===================================================================== FAILURES ======================================================================
___________________________________________________________________ test_failing ____________________________________________________________________

    def test_failing():
>       assert 1+1 == 3
E       assert (1 + 1) == 3

test_failing.py:2: AssertionError
============================================================== short test summary info ==============================================================
FAILED test_failing.py::test_failing - assert (1 + 1) == 3
============================================================ 1 failed, 2 passed in 0.08s ============================================================
  1. 테스트 Fixture: pytest는 테스트 실행 전에 설정 작업을 하고, 실행 후 정리 작업을 할 수 있도록 “픽스처”라는 기능을 제공합니다. 이를 통해 중복 코드를 줄이고, 테스트 환경을 설정하는 코드를 재사용할 수 있습니다.

    • 주요 특징
      1. 설정 및 초기화: 테스트 함수에서 필요한 데이터나 환경을 미리 설정할 수 있습니다.
      2. 재사용 가능: 여러 테스트에서 동일한 설정을 재사용할 수 있습니다.
      3. 자동 주입: 테스트 함수에서 직접 픽스처를 호출하지 않아도, pytest가 자동으로 해당 함수에 전달합니다.
      4. 스코프 관리: 픽스처의 수명을 function, class, module, session 단위로 설정할 수 있습니다.
     import pytest
    
     @pytest.fixture
     def sample_data():
         return {"name": "Alice", "age": 25}
    
     def test_sample_data(sample_data):
         assert sample_data['name'] == "Alice"
         assert sample_data['age'] == 25
    

    위 코드에서 sample_data()는 픽스처로 정의되었으며, pytesttest_sample_data 함수가 실행될 때 해당 픽스처를 자동으로 주입합니다. 이 경우, 테스트 함수는 픽스처에서 반환된 데이터를 사용하게 됩니다.

    • Fixture Scope
      • fixture의 기본 스코프는 function입니다. 즉, 각 테스트 함수마다 새로운 인스턴스가 생성됩니다. pytest는 다양한 스코프를 지원하며, 이를 통해 픽스처가 테스트 함수, 클래스, 모듈 또는 세션단위로 재사용되도록 설정할 수 있습니다.
     import pytest
    
     @pytest.fixture(scope = "module")
     def sample_data():
         print("픽스터 설정")
         return {"name": "Alice", "age": 25}
    
     def test_sample_data_1(sample_data):
         assert sample_data['name'] == "Alice"
    
     def test_sample_data_2(sample_data):
         assert sample_data['age'] == 25
    

    위 코드에서 scope="module"로 설정된 픽스처는 모듈 내에서 한 번만 생성됩니다. 따라서 두 개의 테스트 함수(test_sample_data_1, test_sample_data_2)에서 같은 픽스처 인스턴스를 공유하게 됩니다. print 문을 통해 픽스처가 몇 번 호출되는지 확인할 수 있습니다.

    • 여러 픽스처 사용하기 하나의 테스트 함수에서 여러 픽스처를 사용할 수도 있습니다. pytest는 자동으로 필요한 픽스처들을 각 테스트 함수에 전달합니다.
     import pytest
    
     @pytest.fixture
     def user_data():
         return {"name": "Alice"}
    
     @pytest.fixture
     def age_data():
         return {"age": 25}
    
     def test_multiple_fixtures(user_data, age_data):
         assert user_data['name'] == "Alice"
         assert age_data['age'] == 25
    
  2. 매개변수화된(Parameterized) 테스트: 동일한 테스트 함수를 다양한 입력값으로 여러 번 실행할 수 있도록 매개벼수화 기능을 제공합니다. 이를 통해 중복된 테스트 코드를 줄일 수 있습니다.

@pytest.mark.parametrize("input, expected", [
    (1+1, 2),
    (1+2, 3),
    (1+3, 4)
])
def test_addition(input, expected):
    assert input == expected
  1. 마커 (Markers): pytest는 테스트를 그룹화하거나 특정 조건에 따라 테스트를 실행할 수 있는 마커 기능을 제공합니다. 예를들어, 특정 테스트를 건너뛰거나, 속도에 따라 그룹화하여 실행할 수 있습니다.
@pytest.mark.skip(reason = "테스트를 건너뜁니다.")
def test_skip():
    assert 1 == 1

@pytest.mark.slow
def test_slow_function():
    # 느리게 실행되는 테스트
    assert slow_function() == True