python - 在单个测试中禁用 pytest 警告捕获
问题描述
我通常喜欢 pytest 警告捕获钩子,因为我可以使用它来强制我的测试套件不触发任何警告。但是,我有一项测试需要将警告正确打印到 stderr 才能正常工作。
如何仅针对一项测试禁用警告捕获?
例如,像
def test_warning():
mystderr = StringIO()
sys.stderr = mystderr
warnings.warn('warning')
assert 'UserWarning: warning' in mystderr.getvalue()
(我知道我可以使用capsys
,我只是想展示基本思想)
解决方案
由于这次讨论的范围缩小,我认为这个问题最好标题为“在 pytest 中,如何在单个测试中捕获警告及其标准错误输出?”。鉴于建议的改写,我认为答案是“它不能,你需要一个单独的测试”。
如果没有标准错误捕获要求,您应该能够为此使用@pytest.mark.filterwarnings
注释。
@pytest.mark.filterwarnings("ignore")
def test_one():
assert api_v1() == 1
来自: https ://docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings
@wim 在评论中指出,尽管如此,这不会捕获警告,并且他列出的答案以标准方式捕获并断言警告。
如果有 stderr 输出但没有抛出 Python 警告,则 capsys 将是该技术,正如您所说的 https://docs.pytest.org/en/latest/capture.html
由于 pytest 实现的性质,我认为在 pytest 测试中同时执行这两种操作没有意义。
如前所述,pytest 将 stderr 等重定向到内部记录器。其次,它定义了自己的警告处理程序 https://github.com/pytest-dev/pytest/blob/master/src/_pytest/warnings.py#L59
它的想法与这个问题的答案相似: https ://stackoverflow.com/a/5645133/5729872
我对 redefining 进行了一些warnings.showwarning()
探讨,它在 vanilla python 上运行良好,但 pytest 也故意重新初始化它。
不能在 pytest 中工作,只能直接使用 python -->
def func(x):
warnings.warn('wwarn')
print(warnings.showwarning.__doc__)
# print('ewarn', file=sys.stderr)
return x + 1
sworig = warnings.showwarning
def showwarning_wrapper(message, category, filename, lineno, file=None, line=None):
"""Local override for showwarning()"""
print('swwrapper({})'.format(file) )
sworig(message,category,filename,lineno,file,line)
warnings.showwarning = showwarning_wrapper
<-- 不能在 pytest 中工作,只能在 python 中工作
您可能可以在您的测试用例中放置一个警告处理程序,该处理程序重新输出到 stderr ......但这并不能证明测试中的代码,在这一点上。
归根结底,它是您的系统。如果在考虑了@wim 提出的关于测试 stderr 本身可能证明不多的观点之后,您决定仍然需要它,我建议将 Python 警告对象(python 调用者层)的测试与 stderr 的内容(调用 shell层)。第一个测试将只查看 Python 警告对象。新的第二个测试用例将通过或类似的方式将被测库作为脚本调用popen()
,并对产生的标准错误和输出进行断言。
推荐阅读
- python - tkinter 如何使用位置将滚动条附加到列表框?
- java - 选择另一个时取消选中复选框
- wordpress - WP 插件不适用于 ajax 加载的内容
- date - 在 SPSS 中管理日期 - 以月为单位的时差
- java - 如何得到我的手指在哪里,在哪个布局上?
- eclipse - Eclipse 中的 Maven 安装命令失败,错误访问被拒绝,错误代码 403,禁止访问
- powershell - 等待使用凭据启动的进程时访问被拒绝
- c - 如何理解为什么会发生 ARM 异常?
- ruby-on-rails - Cloudinary 如何更新/编辑数组中的图像
- java - Netty SslHandler 抛出 IllegalReferenceCountException