Python의 모의 함수

Migel Hewage Nimesha 2024년2월15일
  1. Python에서 Pytest Mock 설정 및 설치
  2. Python에서 함수 모의
  3. 결론
Python의 모의 함수

unittest.mock 또는 Mock 함수는 테스트 중인 시스템의 구성 요소를 mock 개체로 대체하고 부품이 어떻게 사용되었는지에 대한 어설션을 만들 수 있는 Python 테스트용 라이브러리입니다.

unittest.mock은 코어 Mock 클래스를 제공하여 테스트 스위트 전체에 스텁 호스트를 생성할 필요가 없습니다.

프로세스를 실행한 후 사용된 메소드 또는 속성과 호출된 인수를 어설션할 수 있습니다. 일반적인 방법으로 반환 값을 지정하고 필요한 속성을 설정할 수도 있습니다.

또한 Mock은 테스트 범위 내에서 패칭 모듈 및 클래스 수준 속성을 처리할 수 있는 patch() 데코레이터를 제공하고 고유한 개체를 생성하기 위한 헬퍼 sentinel을 제공합니다.

‘Mock’은 ‘unittest’와 함께 사용하기 위해 만들어졌으며 대부분의 모킹 프레임워크에서 사용되는 ‘record-to-replay’ 대신 ‘action-to-assertion’ 패턴을 기반으로 합니다. 이전 버전의 Python에 대한 unittest.mock의 백포트가 있습니다.

Python에서 Pytest Mock 설정 및 설치

unittest와 달리 pytest는 내장 Python 패키지가 아니며 설치가 필요합니다. 터미널에 아래 명령어를 입력하여 설치할 수 있습니다.

pip install pytest

참고로 unittest의 모범 사례는 다음과 같이 pytest에도 적용됩니다.

  1. 모든 단위 테스트를 포함하려면 tests/ 디렉토리가 필요합니다.
  2. 파일 이름은 항상 tests_로 시작해야 합니다.
  3. 함수 이름은 항상 the test로 시작해야 합니다.

체커가 수행된 단위 테스트를 찾을 수 있도록 이름 지정 표준을 준수해야 합니다.

사용하기 전에 pytest-mock을 설치해야 합니다. 다음은 pip를 사용하여 설치하는 방법입니다.

pip install pytest-mock

이것은 Pytest용 플러그인입니다. 따라서 아직 수행하지 않은 경우 Pytest가 설치됩니다.

Python에서 함수 모의

시작하려면 운영 체제로 Windows를 사용하는지 Linux를 사용하는지 알려주는 간단한 함수 get_os()를 만듭니다.

다음과 같이 app.py라는 파일을 만듭니다.

from time import sleep


def isWindows():
    # This sleep can be some complex operation
    sleep(5)
    return True


def get_os():
    return "Windows is the current OS" if isWindows() else "Linux is the current OS"

이 기능은 isWindows 기능을 사용하여 현재 운영 체제가 Windows인지 여부를 결정합니다. 이 isWindows 기능이 매우 복잡하고 실행하는 데 몇 초가 걸린다고 가정하면 호출될 때마다 프로그램을 5초 동안 절전 모드로 전환하여 이 느리게 진행되는 기능을 시뮬레이션할 수 있습니다.

다음은 get_os() 함수에 대한 pytest입니다.

test_app.py에서 pytest라는 파일을 만듭니다.

from app import get_os


def test_get_os():
    assert get_os() == "Windows is the current OS"

get_os()는 더 느린 기능인 isWindows를 호출하므로 테스트가 느리게 진행됩니다. 이것은 pytest 실행의 아래 출력에서 볼 수 있습니다.

5.02초가 소요되었으며 현재 인스턴스에 따라 다를 수 있습니다.

모의 함수 파이썬 - 출력 1

단위 테스트는 빨라야 하고 몇 초 만에 수백 개의 테스트를 수행할 수 있어야 합니다. 테스트 스위트는 5초가 걸리는 단일 테스트로 인해 속도가 느려지므로 모의를 적용하면 삶이 더 쉬워집니다.

느리게 진행되는 함수를 패치하면 5초 동안 머물지 않고 get_os() 함수의 동작을 확인할 수 있습니다.

pytest-mock을 사용하여 이 함수를 조롱해 보겠습니다.

Pytest-mockmocker라는 고정 장치와 Python의 통합 모킹 구조 위에 훌륭한 인터페이스를 제공합니다. 모커에서 모의 및 패치 함수를 호출하고 이를 테스트 함수의 인수로 전송하여 모커를 사용할 수 있습니다.

isWindows 함수가 귀중한 5초를 기다리지 않고 True를 반환하도록 하려면 다음과 같이 패치할 수 있습니다.

mocker.patch("app.isWindows", return_value=True)

여기서 isWindowsapp 모듈의 기능이므로 app.isWindows로 참조해야 합니다. isWindows만 패치하면 test_app 파일에서 존재하지 않는 isWindows라는 함수를 패치하려고 시도합니다.

형식은 항상 <module_name>.<function_name>이며 올바르게 모의하는 방법을 아는 것이 중요합니다.

다음은 패치 후 수정된 테스트 기능을 설명합니다.

from app import get_os

# using'mocker' fixture provided by pytest-mock


def test_get_os(mocker):
    # mocking the slow-going function and returning True always
    mocker.patch("app.isWindows", return_value=True)
    assert get_os() == "Windows is the current OS"

이제 이 테스트를 실행하면 훨씬 더 빨리 완료됩니다.

mock function python - output 2

보시다시피 테스트는 0.02초 밖에 걸리지 않았기 때문에 느리게 진행되는 기능을 성공적으로 패치하고 테스트 스위트를 가속화했습니다.

모킹의 또 다른 이점은 모의 함수가 무엇이든 반환하도록 할 수 있고 오류를 발생시켜 해당 시나리오에서 코드가 어떻게 처리되는지 테스트할 수도 있다는 것입니다.

여기에서 isWindowsFalse를 반환하는 경우를 테스트하려면 다음 테스트를 작성하십시오.

from app import get_os


def test_os_isLinux(mocker):
    mocker.patch(
        "app.isWindows", return_value=False
    )  # set the return value to be False
    assert get_os() == "Linux is the current OS"

모커와 함께 제공되는 모의 및 패치는 모두 기능 범위이므로 특정 기능에만 사용할 수 있습니다. 결과적으로 서로 다른 테스트에서 동일한 기능에 대한 패치 간에 충돌이 발생하지 않습니다.

결론

모킹은 테스트 중인 애플리케이션 구성 요소를 해당 구성 요소의 더미 구현인 모의로 대체하는 방법입니다. 모의를 통해 우리는 속도 향상, 더 빠르게 실행되는 테스트가 매우 유익하고 테스트 중에 원하지 않는 부작용을 피하는 등의 이점을 얻을 수 있습니다.

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.

관련 문장 - Python Mock