파이테스트를 사용하여 오류가 발생하지 않았는지 확인하는 방법
우리가 그런 smth를 가지고 있다고 가정해 보겠습니다.
import py, pytest
ERROR1 = ' --- Error : value < 5! ---'
ERROR2 = ' --- Error : value > 10! ---'
class MyError(Exception):
def __init__(self, m):
self.m = m
def __str__(self):
return self.m
def foo(i):
if i < 5:
raise MyError(ERROR1)
elif i > 10:
raise MyError(ERROR2)
return i
# ---------------------- TESTS -------------------------
def test_foo1():
with pytest.raises(MyError) as e:
foo(3)
assert ERROR1 in str(e)
def test_foo2():
with pytest.raises(MyError) as e:
foo(11)
assert ERROR2 in str(e)
def test_foo3():
....
foo(7)
....
Q: MyError가 발생하지 않도록 test_foo3()를 테스트하려면 어떻게 해야 합니까?제가 테스트할 수 있다는 것은 명백합니다.
def test_foo3():
assert foo(7) == 7
하지만 저는 그것을 파이테스트로 테스트하고 싶습니다. ㅠㅠ어떻게든 가능합니까?예를 들어, 어떤 경우, 함수 "foo"는 반환값이 전혀 없습니다.
def foo(i):
if i < 5:
raise MyError(ERROR1)
elif i > 10:
raise MyError(ERROR2)
이런 식으로 테스트하는 것이 말이 될 수 있습니다, 임호.
예기치 않은 예외가 발생하면 테스트가 실패합니다.foo(7)만 호출하면 MyError가 발생하지 않는지 테스트할 수 있습니다.따라서 다음과 같이 하면 충분합니다.
def test_foo3():
foo(7)
명시적으로 설명하고 이에 대한 Assert 문을 작성하려면 다음 작업을 수행할 수 있습니다.
def test_foo3():
try:
foo(7)
except MyError:
pytest.fail("Unexpected MyError ..")
이 질문에 대답한 이후로, 파이테스트 문서는 여기서 언급할 가치가 있는 이 주제에 대한 정보를 업데이트했습니다.
https://docs.pytest.org/en/6.2.x/example/parametrize.html#parametrizing-conditional-raising
일부 다른 답변과 비슷하지만 다음을 사용합니다.parametrize
그리고 새로운 기본 제공 기능nullcontext
그것은 용액을 정말 깨끗하게 만듭니다.
잠재적인 Python 3.7+의 예는 다음과 같습니다.
from contextlib import nullcontext as does_not_raise
import pytest
@pytest.mark.parametrize(
"example_input,expectation",
[
(3, does_not_raise()),
(2, does_not_raise()),
(1, does_not_raise()),
(0, pytest.raises(ZeroDivisionError)),
],
)
def test_division(example_input, expectation):
"""Test how much I know division."""
with expectation:
assert (6 / example_input) is not None
사용.parametrize
이러한 방식을 통해 다음과 같은 OP의 테스트 사례를 결합할 수 있습니다.
@pytest.mark.parametrize(
"example_input,expectation,message",
[
(3, pytest.raises(MyError), ERROR1),
(11, pytest.raises(MyError), ERROR2),
(7, does_not_raise(), None),
],
)
def test_foo(example_input, expectation, message):
with expectation as e:
foo(example_input)
assert message is None or message in str(e)
이러한 방식으로 작업을 수행하면 예외가 발생하지 않았는지 테스트할 수 있습니다.nullcontext
는 선택적 컨텍스트 관리자(pytest.raises
이 경우).실제로 아무것도 하지 않기 때문에 특정 예외를 제기하지 않았는지 테스트하려면 다른 답 중 하나를 확인해야 합니다.
오이신이 언급한 것 위에 건물을 짓는 것.
간단하게 만들 수 있습니다.not_raises
파이테스트와 유사하게 작용하는 기능raises
:
from contextlib import contextmanager
@contextmanager
def not_raises(exception):
try:
yield
except exception:
raise pytest.fail("DID RAISE {0}".format(exception))
만약 당신이 계속 가지고 싶다면 이것은 괜찮습니다.raises
상대편이 있기 때문에 테스트를 더 쉽게 읽을 수 있습니다.그러나 본질적으로 테스트할 코드 블록을 자체 라인에서 실행하는 것 외에는 아무 것도 필요하지 않습니다. 어쨌든 해당 블록이 오류를 발생시키는 즉시 파이테스트가 실패합니다.
저는 안 올리는 게 효과가 있을지 궁금했습니다.이에 대한 간단한 테스트는 (test_notraises)입니다.py):
from contextlib import contextmanager
@contextmanager
def not_raises(ExpectedException):
try:
yield
except ExpectedException, err:
raise AssertionError(
"Did raise exception {0} when it should not!".format(
repr(ExpectedException)
)
)
except Exception, err:
raise AssertionError(
"An unexpected exception {0} raised.".format(repr(err))
)
def good_func():
print "hello"
def bad_func():
raise ValueError("BOOM!")
def ugly_func():
raise IndexError("UNEXPECTED BOOM!")
def test_ok():
with not_raises(ValueError):
good_func()
def test_bad():
with not_raises(ValueError):
bad_func()
def test_ugly():
with not_raises(ValueError):
ugly_func()
효과가 있는 것 같습니다.하지만 시험에서 그것이 정말 잘 읽히는지는 잘 모르겠습니다.
언급URL : https://stackoverflow.com/questions/20274987/how-to-use-pytest-to-check-that-error-is-not-raised
'bestsource' 카테고리의 다른 글
즐겨찾기 Visual Studio 바로 가기 키 (0) | 2023.06.13 |
---|---|
과학적 표기법을 비활성화하려면 어떻게 해야 합니까? (0) | 2023.06.13 |
UIBarButtonItem 글꼴 변경 (0) | 2023.06.13 |
여러 열이 있는 SQL Server의 'In' 절 (0) | 2023.06.13 |
Conda: github에서 직접 설치/업그레이드 (0) | 2023.06.13 |