r잡초처럼
바른 프로그래밍
r잡초처럼
전체 방문자
오늘
어제
  • 분류 전체보기 (124)
    • FastAPI (7)
    • 끄적끄적 (2)
    • Python (17)
    • Django (31)
    • Database (2)
    • Docker (7)
    • 디자인패턴 (2)
    • CS 공부 (12)
      • 알고리즘 (2)
      • 자료 구조 (1)
      • 네트워크 (7)
      • IT 지식 (1)
      • 운영체제 (1)
    • 기타 팁들 (10)
    • Aws (2)
    • 독서 (1)
    • 코딩테스트 공부 (1)
      • 백준 (0)
      • 프로그래머스 (1)
    • DevOps (13)
    • TIL (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • validate
  • fastapi
  • query param
  • Batch
  • 5장 회사에서 하는 랜 구성
  • pycharm
  • 케이블의 종류
  • 파이썬 클린 코드
  • cp949
  • 모두의 네트워크
  • CS 지식
  • depends
  • 책 리뷰
  • docker
  • 컴퓨터 기본 지식
  • 7장
  • 전기 신호
  • 랜 카드
  • 상속 안티 패턴
  • 네트워크
  • 완벽한 IT 인프라 구축을 위한 Docker
  • 물리 계층
  • 6장
  • encoding
  • poetry
  • dotenv
  • pytest
  • 랜과 왠
  • 상속과 컴포지션
  • preonboarding

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
r잡초처럼

바른 프로그래밍

Python

Pytest - 2. Fixture 알아보기

2023. 2. 1. 20:19

어제에 간단하게 예제를 살펴보았다. 이번에는 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

 

How to use fixtures — pytest documentation

Scope: sharing fixtures across classes, modules, packages or session Fixtures requiring network access depend on connectivity and are usually time-expensive to create. Extending the previous example, we can add a scope="module" parameter to the @pytest.fix

docs.pytest.org

https://velog.io/@sangyeon217/pytest-fixture#scope-%EC%84%A4%EC%A0%95

 

Pytest Fixture 생성

Pytest Fixture 에 대한 포스팅 입니다.

velog.io

 

'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
    'Python' 카테고리의 다른 글
    • 결합과 추상화 - 2
    • Pytest - 3. Monkeypatching functions
    • Pytest 사용하기 - 1. 간단한 예제
    • 파이썬으로 배우는 자료구조 핵심 원리
    r잡초처럼
    r잡초처럼
    오늘보다 내일 더 나은 개발자가 되기 위한 노력을 기록하는 블로그 입니다.

    티스토리툴바