[python] pytest에서 예외가 발생했다고 올바르게 주장하는 방법은 무엇입니까?

암호:

# coding=utf-8
import pytest


def whatever():
    return 9/0

def test_whatever():
    try:
        whatever()
    except ZeroDivisionError as exc:
        pytest.fail(exc, pytrace=True)

산출:

================================ test session starts =================================
platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
plugins: django, cov
collected 1 items

pytest_test.py F

====================================== FAILURES ======================================
___________________________________ test_whatever ____________________________________

    def test_whatever():
        try:
            whatever()
        except ZeroDivisionError as exc:
>           pytest.fail(exc, pytrace=True)
E           Failed: integer division or modulo by zero

pytest_test.py:12: Failed
============================== 1 failed in 1.16 seconds ==============================

pytest print traceback을 만드는 방법, whatever함수에서 예외가 발생한 위치를 볼 수 있습니까?



답변

pytest.raises(Exception) 당신이 필요한 것입니다.

암호

import pytest

def test_passes():
    with pytest.raises(Exception) as e_info:
        x = 1 / 0

def test_passes_without_info():
    with pytest.raises(Exception):
        x = 1 / 0

def test_fails():
    with pytest.raises(Exception) as e_info:
        x = 1 / 1

def test_fails_without_info():
    with pytest.raises(Exception):
        x = 1 / 1

# Don't do this. Assertions are caught as exceptions.
def test_passes_but_should_not():
    try:
        x = 1 / 1
        assert False
    except Exception:
        assert True

# Even if the appropriate exception is caught, it is bad style,
# because the test result is less informative
# than it would be with pytest.raises(e)
# (it just says pass or fail.)

def test_passes_but_bad_style():
    try:
        x = 1 / 0
        assert False
    except ZeroDivisionError:
        assert True

def test_fails_but_bad_style():
    try:
        x = 1 / 1
        assert False
    except ZeroDivisionError:
        assert True

산출

============================================================================================= test session starts ==============================================================================================
platform linux2 -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4
collected 7 items

test.py ..FF..F

=================================================================================================== FAILURES ===================================================================================================
__________________________________________________________________________________________________ test_fails __________________________________________________________________________________________________

    def test_fails():
        with pytest.raises(Exception) as e_info:
>           x = 1 / 1
E           Failed: DID NOT RAISE

test.py:13: Failed
___________________________________________________________________________________________ test_fails_without_info ____________________________________________________________________________________________

    def test_fails_without_info():
        with pytest.raises(Exception):
>           x = 1 / 1
E           Failed: DID NOT RAISE

test.py:17: Failed
___________________________________________________________________________________________ test_fails_but_bad_style ___________________________________________________________________________________________

    def test_fails_but_bad_style():
        try:
            x = 1 / 1
>           assert False
E           assert False

test.py:43: AssertionError
====================================================================================== 3 failed, 4 passed in 0.02 seconds ======================================================================================

e_info예외 개체 를 저장하여 세부 정보를 추출 할 수 있습니다. 예를 들어 예외 호출 스택 또는 다른 중첩 예외를 확인하려는 경우.


답변

다음과 같은 의미입니까?

def test_raises():
    with pytest.raises(Exception) as execinfo:
        raise Exception('some info')
    # these asserts are identical; you can use either one   
    assert execinfo.value.args[0] == 'some info'
    assert str(execinfo.value) == 'some info'


답변

pytest에서 이러한 종류의 사례를 처리하는 두 가지 방법이 있습니다.

  • pytest.raises기능 사용

  • pytest.mark.xfail데코레이터 사용하기

사용법 pytest.raises:

def whatever():
    return 9/0
def test_whatever():
    with pytest.raises(ZeroDivisionError):
        whatever()

사용법 pytest.mark.xfail:

@pytest.mark.xfail(raises=ZeroDivisionError)
def test_whatever():
    whatever()

출력 pytest.raises:

============================= test session starts ============================
platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 --
/usr/local/python_2.7_10/bin/python
cachedir: .cache
rootdir: /home/user, inifile:
collected 1 item

test_fun.py::test_whatever PASSED


======================== 1 passed in 0.01 seconds =============================

pytest.xfail마커 출력 :

============================= test session starts ============================
platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 --
/usr/local/python_2.7_10/bin/python
cachedir: .cache
rootdir: /home/user, inifile:
collected 1 item

test_fun.py::test_whatever xfail

======================== 1 xfailed in 0.03 seconds=============================

현상태대로 설명서를 말한다 :

pytest.raises예외를 테스트하는 경우 의도적으로 자체 코드에서 의도적으로 발생하는 예외에 대해 사용 하는 것이 좋을 수도 있지만 @pytest.mark.xfail, 검사 기능과 함께 사용 하면 수정되지 않은 버그 (테스트에서 “어떻게 발생해야 하는지를 설명하는”) 또는 종속성의 버그를 문서화하는 것과 같은 경우에 더 좋습니다. .


답변

당신은 시도 할 수 있습니다

def test_exception():
    with pytest.raises(Exception) as excinfo:
        function_that_raises_exception()
    assert str(excinfo.value) == 'some info' 


답변

pytest는 끊임없이 발전하고 최근의 멋진 변화 중 하나를 통해 동시에 테스트 할 수 있습니다

  • 예외 유형 (엄격한 테스트)
  • 오류 메시지 (정규 표현식을 사용하여 엄격하거나 느슨하게 검사)

설명서의 두 가지 예 :

with pytest.raises(ValueError, match='must be 0 or None'):
    raise ValueError('value must be 0 or None')
with pytest.raises(ValueError, match=r'must be \d+$'):
    raise ValueError('value must be 42')

나는 많은 프로젝트에서 그 접근법을 사용하고 있으며 매우 좋아합니다.


답변

올바른 방법을 사용하고 pytest.raises있지만 여기 주석에서 흥미로운 대안을 찾았 으며이 질문을 읽는 독자를 위해 저장하고 싶습니다.

try:
    thing_that_rasises_typeerror()
    assert False
except TypeError:
    assert True


답변

이 솔루션은 우리가 사용하는 것입니다.

def test_date_invalidformat():
    """
    Test if input incorrect data will raises ValueError exception
    """
    date = "06/21/2018 00:00:00"
    with pytest.raises(ValueError):
        app.func(date) #my function to be tested

pytest, https://docs.pytest.org/en/latest/reference.html#pytest-raises를 참조하십시오