如何使用 pytest 断言不引发警告
How to use pytest to assert NO Warning is raised
我想确保在一个断言中根本没有警告。
无法在 pytest documentation about warnings 中找到任何明确的答案。
我试过了,我想 None
可能意味着 "nothing":
def test_AttrStr_parse_warnings():
"""Check _AttrStr.parse() raises proper warnings in proper cases."""
with pytest.warns(None):
_AttrStr('').parse()
但是这个断言也总是正确的,例如,测试不会失败,即使实际上引发了警告:
def test_AttrStr_parse_warnings():
"""Check _AttrStr.parse() raises proper warnings in proper cases."""
with pytest.warns(None):
_AttrStr('').parse()
warnings.warn('any message')
对于 pytest >= 7.0
The doc 现在明确提到这种情况应该以这种方式解决(没有 pytest):
with warnings.catch_warnings():
warnings.simplefilter("error")
...
虽然这可能无法完全解决某些情况(动态检查:参见 this post)。
下面为 pytest < 7.0 建议的解决方案现在引发了 DeprecationWarning。感谢@Warren-Weckesser 在评论中指出这一点!
pytest < 7.0 的可能解决方案
然而它并没有计划像这样使用,它可以“记录”任何可能引发的警告,并使用它来添加另一个断言以确保引发警告的数量是 0
:
def test_AttrStr_parse_warnings():
"""Check parse() raises proper warnings in proper cases."""
with pytest.warns(None) as record:
_AttrStr('').parse()
assert len(record) == 0
为确保它有效:在第二个断言中添加 warnings.warn('any message')
让测试失败。
如果您有测试其他功能的测试,但您还想断言没有发出警告,您可以使用装饰器。这是我根据 zezollo
之前接受的答案写的
def no_warnings(func):
def wrapper_no_warnings(*args, **kwargs):
with pytest.warns(None) as warnings:
func(*args, **kwargs)
if len(warnings) > 0:
raise AssertionError(
"Warnings were raised: " + ", ".join([str(w) for w in warnings])
)
return wrapper_no_warnings
然后您可以修饰测试 class 函数以添加此断言。
class MyTestClass(TestCase)
@no_warnings
def test_something(self):
# My important test
self.assertTrue(True)
我想确保在一个断言中根本没有警告。
无法在 pytest documentation about warnings 中找到任何明确的答案。
我试过了,我想 None
可能意味着 "nothing":
def test_AttrStr_parse_warnings():
"""Check _AttrStr.parse() raises proper warnings in proper cases."""
with pytest.warns(None):
_AttrStr('').parse()
但是这个断言也总是正确的,例如,测试不会失败,即使实际上引发了警告:
def test_AttrStr_parse_warnings():
"""Check _AttrStr.parse() raises proper warnings in proper cases."""
with pytest.warns(None):
_AttrStr('').parse()
warnings.warn('any message')
对于 pytest >= 7.0
The doc 现在明确提到这种情况应该以这种方式解决(没有 pytest):
with warnings.catch_warnings():
warnings.simplefilter("error")
...
虽然这可能无法完全解决某些情况(动态检查:参见 this post)。
下面为 pytest < 7.0 建议的解决方案现在引发了 DeprecationWarning。感谢@Warren-Weckesser 在评论中指出这一点!
pytest < 7.0 的可能解决方案
然而它并没有计划像这样使用,它可以“记录”任何可能引发的警告,并使用它来添加另一个断言以确保引发警告的数量是 0
:
def test_AttrStr_parse_warnings():
"""Check parse() raises proper warnings in proper cases."""
with pytest.warns(None) as record:
_AttrStr('').parse()
assert len(record) == 0
为确保它有效:在第二个断言中添加 warnings.warn('any message')
让测试失败。
如果您有测试其他功能的测试,但您还想断言没有发出警告,您可以使用装饰器。这是我根据 zezollo
之前接受的答案写的def no_warnings(func):
def wrapper_no_warnings(*args, **kwargs):
with pytest.warns(None) as warnings:
func(*args, **kwargs)
if len(warnings) > 0:
raise AssertionError(
"Warnings were raised: " + ", ".join([str(w) for w in warnings])
)
return wrapper_no_warnings
然后您可以修饰测试 class 函数以添加此断言。
class MyTestClass(TestCase)
@no_warnings
def test_something(self):
# My important test
self.assertTrue(True)