Python 如何使用pytest检查未引发错误
假设我们有这样的smth:Python 如何使用pytest检查未引发错误,python,pytest,raise,Python,Pytest,Raise,假设我们有这样的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):
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)
....
但是我想通过pytest.raises()来测试这一点。有可能吗?
例如:在一个例子中,函数“foo”根本没有返回值
def foo(i):
if i < 5:
raise MyError(ERROR1)
elif i > 10:
raise MyError(ERROR2)
def foo(i):
如果i<5:
升起我的错误(错误1)
如果i>10:
升起我的错误(错误2)
以这种方式进行测试是有意义的,imho。如果测试引发任何类型的意外异常,它将失败。您只需调用foo(7),就可以测试是否没有引发MyError。因此,以下内容就足够了:
def test_foo3():
foo(7)
如果希望显式并为此编写assert语句,可以执行以下操作:
def test_foo3():
try:
foo(7)
except MyError:
pytest.fail("Unexpected MyError ..")
我很好奇,想看看不加薪是否管用。这方面的一个快速测试是 (test_notraises.py): 它似乎确实起作用了。然而,我不确定它是否真的在报纸上读得好
测试。在Oisin提到的基础上构建 您可以创建一个简单的
not_raises
函数,其作用类似于pytest的raises
:
from contextlib import contextmanager
@contextmanager
def not_raises(exception):
try:
yield
except exception:
raise pytest.fail("DID RAISE {0}".format(exception))
如果您希望坚持使用
提升
副本,从而使测试更具可读性,那么这是很好的。但实际上,除了在自己的代码行上运行要测试的代码块之外,您并不需要其他任何东西——只要代码块出现错误,pytest就会失败。谢谢,它是有效的,但它似乎更像是一种黑客行为,而不是一种干净的解决方案。例如,对foo(4)的测试将失败,但不是由于断言错误。对foo(4)的测试将失败,因为它将抛出一个不期望的异常。另一种方法是将其包装在try-catch块中,并使用特定消息失败。我会更新我的答案。如果你有很多这样的情况,在一个简单的函数中写下它可能会很有用:``def not_raises(error_class,func,*args,**kwargs):```````或者您也可以像pytest那样使用类似的方法编写一个测试。如果你这样做,我建议你写一份公关,让所有人受益。:)(存储库在中)。@paraklet-pytest的主要口号是。在pytest为您处理细节时,您可以像Faruk的第一个示例中那样编写测试,这非常符合pytest的精神。对我来说,第一个例子是“干净的解决方案”,第二个看起来不必要的冗长。我喜欢代码可读。如果我看到pytest.notRaises()
我清楚地看到测试的目的是检查是否没有抛出异常。如果我只是执行代码,没有任何断言,我的第一个想法是“这里缺少了一些东西…”。是的,我可以为此写评论,但我更喜欢代码是自解释的,而不是注释。它看起来像是在搜索问题,代码测试foo(7)
很好。您将获得正确的消息,并且使用所有pytest输出进行调试将更容易。您从@Faruk('Unexpected error…“
)强制执行的建议与错误无关,您将被卡住。你能做的唯一一件事就是更好地表达你的意图,比如test\u foo3\u对\u range()内的\u integers\u工作。
。相关:我希望这是py.test中内置的;在某些情况下,它会使测试更具可读性。特别是与@pytest.mark.parametize一起使用时。我非常欣赏这种方法的代码可读性!为python3更新
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()
from contextlib import contextmanager
@contextmanager
def not_raises(exception):
try:
yield
except exception:
raise pytest.fail("DID RAISE {0}".format(exception))