- Pytest:帮助您编写更好的程序
- 完整的 Pytest 文档
- 安装和入门
- 使用和调用
- 在现有测试套件中使用 pytest
- 测试中断言的编写和报告
- Pytest 夹具:显式、模块化、可扩展
- 用属性标记测试函数
- MonkeyPatching / Mocking 模块和环境
- 临时目录和文件
- 捕获 stdout/stderr 输出
- 捕获警告
- 模块和测试文件的 Doctest 集成
- 跳过和 xfail:处理无法成功的测试
- 参数化夹具和测试功能
- 缓存:使用交叉测试运行状态
- UnitTest.TestCase 支持
- 运行为鼻子编写的测试
- 经典的 Xunit 风格设置
- 安装和使用插件
- 编写插件
- 登录
- 良好的集成实践
- 古怪的测试
- Pytest 导入机制和 sys.path/PYTHONPATH
- 设置 bash 完成
- API 引用
- _pytest.hookspec
- _pytest.python_api
- _pytest.outcomes
- _pytest.config
- _pytest.mark
- _pytest.recwarn
- _pytest.assertion
- _pytest.freeze_support
- _pytest.fixtures
- _pytest.cacheprovider
- _pytest.capture
- _pytest.doctest
- _pytest.junitxml
- _pytest.logging
- _pytest.monkeypatch
- _pytest.pytester
- _pytest.tmpdir
- _pytest.python
- _pytest.nodes
- _pytest.reports
- _pytest._code.code
- _pytest.config.argparsing
- _pytest.main
- pluggy.callers
- _pytest.config.exceptions
- py.test 2.0.0:断言++、UnitTest++、Reporting++、Config++、Docs++
- 示例和自定义技巧
- 配置
- 贡献开始
- 向后兼容策略
- Python 2.7 和 3.4 支持
- 企业版 pytest
- 项目实例
- 历史笔记
- 弃用和移除
- 发展指南
- 演讲和辅导
捕获警告
从版本开始 3.1
,pytest现在在测试执行期间自动捕获警告,并在会话结束时显示这些警告:
# content of test_show_warnings.py import warnings def api_v1(): warnings.warn(UserWarning("api v1, should use functions from v2")) return 1 def test_one(): assert api_v1() == 1
现在运行pytest将生成以下输出:
$ pytest test_show_warnings.py =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y cachedir: $PYTHON_PREFIX/.pytest_cache rootdir: $REGENDOC_TMPDIR collected 1 item test_show_warnings.py . [100%] ============================= warnings summary ============================= test_show_warnings.py::test_one $REGENDOC_TMPDIR/test_show_warnings.py:5: UserWarning: api v1, should use functions from v2 warnings.warn(UserWarning("api v1, should use functions from v2")) -- Docs: https://docs.pytest.org/en/stable/warnings.html ======================= 1 passed, 1 warning in 0.12s =======================
这个 -W
可以将标志传递给控制将显示哪些警告,甚至将其转换为错误:
$ pytest -q test_show_warnings.py -W error::UserWarning F [100%] ================================= FAILURES ================================= _________________________________ test_one _________________________________ def test_one(): > assert api_v1() == 1 test_show_warnings.py:10: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def api_v1(): > warnings.warn(UserWarning("api v1, should use functions from v2")) E UserWarning: api v1, should use functions from v2 test_show_warnings.py:5: UserWarning ========================= short test summary info ========================== FAILED test_show_warnings.py::test_one - UserWarning: api v1, should use ... 1 failed in 0.12s
相同的选项可以在 pytest.ini
或 pyproject.toml
使用文件 filterwarnings
ini选项。例如,下面的配置将忽略与正则表达式匹配的所有用户警告和特定的弃用警告,但会将所有其他警告转换为错误。
# pytest.ini [pytest] filterwarnings = error ignore::UserWarning ignore:function ham\(\) is deprecated:DeprecationWarning
# pyproject.toml [tool.pytest.ini_options] filterwarnings = [ "error", "ignore::UserWarning", # note the use of single quote below to denote "raw" strings in TOML 'ignore:function ham\(\) is deprecated:DeprecationWarning', ]
当警告与列表中的多个选项匹配时,将执行最后一个匹配选项的操作。
两个 -W
命令行选项和 filterwarnings
ini选项基于python自己的 -W option 和 warnings.simplefilter ,因此请参阅Python文档中的这些部分,以了解其他示例和高级用法。
@pytest.mark.filterwarnings
你可以使用 @pytest.mark.filterwarnings
要向特定测试项添加警告筛选器,允许您更好地控制应在测试、类甚至模块级别捕获哪些警告:
import warnings def api_v1(): warnings.warn(UserWarning("api v1, should use functions from v2")) return 1 @pytest.mark.filterwarnings("ignore:api v1") def test_one(): assert api_v1() == 1
使用标记应用的筛选器优先于命令行上传递的或由 filterwarnings
ini选项。
通过使用 filterwarnings
通过设置 pytestmark
变量:
# turns all warnings into errors for this module pytestmark = pytest.mark.filterwarnings("error")
学分授予Florian Schulze,以便在 pytest-warnings 插件。
禁用警告摘要
虽然不推荐,但您可以使用 --disable-warnings
命令行选项,用于完全禁止来自测试运行输出的警告摘要。
完全禁用警告捕获
此插件在默认情况下启用,但可以在 pytest.ini
文件与:
[pytest] addopts = -p no:warnings
或通过 -p no:warnings
在命令行中。如果测试套件使用外部系统处理警告,这可能很有用。
弃用警告和未决弃用警告
默认情况下,pytest将显示 DeprecationWarning
和 PendingDeprecationWarning
用户代码和第三方库发出的警告 PEP-0565 . 这有助于用户保持代码的现代性,并在有效删除不推荐使用的警告时避免损坏代码。
有时,隐藏一些在您无法控制的代码(如第三方库)中发生的特定拒绝警告很有用,在这种情况下,您可以使用警告筛选选项(ini或标记)忽略这些警告。
例如:
[pytest] filterwarnings = ignore:.*U.*mode is deprecated:DeprecationWarning
这将忽略所有类型的警告 DeprecationWarning
消息的开头与正则表达式匹配的位置 ".*U.*mode is deprecated"
.
注解
如果在解释器级别配置了警告,请使用 PYTHONWARNINGS 环境变量或 -W
命令行选项,pytest在默认情况下不会配置任何过滤器。
同样,Pytest不遵循 PEP-0506
建议重置所有警告筛选器,因为它可能会破坏通过调用 warnings.simplefilter
(见问题) #2430 举个例子)。
确保代码触发拒绝警告
您也可以使用 pytest.deprecated_call()
用于检查某个函数调用是否触发 DeprecationWarning
或 PendingDeprecationWarning
:
import pytest def test_myfunction_deprecated(): with pytest.deprecated_call(): myfunction(17)
此测试将失败,如果 myfunction
调用时不发出弃用警告 17
争论。
默认情况下, DeprecationWarning
和 PendingDeprecationWarning
使用时不会被捕获 pytest.warns()
或 recwarn 因为默认的Python警告过滤器会隐藏它们。如果您希望在自己的代码中记录它们,请使用 warnings.simplefilter('always')
:
import warnings import pytest def test_deprecation(recwarn): warnings.simplefilter("always") myfunction(17) assert len(recwarn) == 1 assert recwarn.pop(DeprecationWarning)
这个 recwarn fixture自动确保在测试结束时重置warnings过滤器,因此不会泄漏全局状态。
使用警告功能断言警告
您可以使用func:pytest.warns`检查代码是否引发了特定的警告,其工作方式类似于 :ref:`raises <assertraises>
:
import warnings import pytest def test_warning(): with pytest.warns(UserWarning): warnings.warn("my warning", UserWarning)
如果未发出相关警告,测试将失败。关键字参数 match
要断言异常与文本或regex匹配,请执行以下操作:
>>> with warns(UserWarning, match='must be 0 or None'): ... warnings.warn("value must be 0 or None", UserWarning) >>> with warns(UserWarning, match=r'must be \d+$'): ... warnings.warn("value must be 42", UserWarning) >>> with warns(UserWarning, match=r'must be \d+$'): ... warnings.warn("this is not here", UserWarning) Traceback (most recent call last): ... Failed: DID NOT WARN. No warnings of type ...UserWarning... was emitted...
也可以对函数或代码串调用func:pytest.warns
:
pytest.warns(expected_warning, func, *args, **kwargs) pytest.warns(expected_warning, "func(*args, **kwargs)")
函数还返回所有引发的警告的列表(如 warnings.WarningMessage
对象),可以查询其他信息:
with pytest.warns(RuntimeWarning) as record: warnings.warn("another warning", RuntimeWarning) # check that only one warning was raised assert len(record) == 1 # check that the message matches assert record[0].message.args[0] == "another warning"
或者,您可以使用 recwarn 夹具(见下文)。
注解
DeprecationWarning
和 PendingDeprecationWarning
被区别对待;见 确保代码触发拒绝警告 .
录制警告
您可以使用func:pytest.warns`或使用 ``recwarn`
固定装置。
要使用func:pytest.warns`记录而不断言任何有关警告的内容,请传递 ``None`
作为预期的警告类型:
with pytest.warns(None) as record: warnings.warn("user", UserWarning) warnings.warn("runtime", RuntimeWarning) assert len(record) == 2 assert str(record[0].message) == "user" assert str(record[1].message) == "runtime"
这个 recwarn
夹具将记录整个功能的警告:
import warnings def test_hello(recwarn): warnings.warn("hello", UserWarning) assert len(recwarn) == 1 w = recwarn.pop(UserWarning) assert issubclass(w.category, UserWarning) assert str(w.message) == "hello" assert w.filename assert w.lineno
两个 recwarn
和func:pytest.warns`为录制的警告返回相同的接口:一个WarningsRecorder实例。要查看记录的警告,可以迭代此实例,调用 ``len`
在它上面获取记录的警告数,或者索引到它上面获取特定的记录警告。
完整的API: WarningsRecorder
.
自定义失败消息
当没有发出警告或满足其他条件时,记录警告提供了生成自定义测试失败消息的机会。
def test(): with pytest.warns(Warning) as record: f() if not record: pytest.fail("Expected a warning!")
如果调用时未发出警告 f
然后 not record
将评估为 True
. 然后你可以打电话 pytest.fail()
带有自定义错误消息。
内部Pytest警告
在某些情况下,Pytest可能会生成自己的警告,例如使用不当或不推荐使用的特性。
例如,如果Pytest遇到匹配的类,它将发出警告。 python_classes
但也定义了 __init__
构造函数,因为这样可以防止类被实例化:
# content of test_pytest_warnings.py class Test: def __init__(self): pass def test_foo(self): assert 1 == 1
$ pytest test_pytest_warnings.py -q ============================= warnings summary ============================= test_pytest_warnings.py:1 $REGENDOC_TMPDIR/test_pytest_warnings.py:1: PytestCollectionWarning: cannot collect test class 'Test' because it has a __init__ constructor (from: test_pytest_warnings.py) class Test: -- Docs: https://docs.pytest.org/en/stable/warnings.html 1 warning in 0.12s
可以使用用于筛选其他类型警告的相同内置机制筛选这些警告。
请阅读我们的 向后兼容策略 要了解我们如何继续取消预测并最终删除功能。
中列出了警告的完整列表 the reference documentation .
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论