ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

pytest内置神器全掌握:monkeypatch、tmp_path与capsys实用技巧清单

pytest内置神器全掌握:monkeypatch、tmp_path与capsys实用技巧清单 pytest内置神器全掌握monkeypatch、tmp_path与capsys实用技巧清单【免费下载链接】pytestThe pytest framework makes it easy to write small tests, yet scales to support complex functional testing项目地址: https://gitcode.com/GitHub_Trending/py/pytestpytest 是 Python 生态中最流行的测试框架之一而它真正强大的地方在于一套开箱即用的内置 fixturemonkeypatch让你安全地打补丁和修改环境变量tmp_path为每个测试提供独立的临时目录capsys则能精准捕获 print 输出的 stdout/stderr。本文为你整理这 3 个 pytest 内置工具的完整技巧清单——不安装任何插件写代码时直接在测试函数参数里声明名字即可自动注入、自动清理。3大pytest内置fixture一页速览在动手之前先用一张表建立整体印象fixture注入方式核心能力自动清理monkeypatchdef test_xxx(monkeypatch):替换属性/函数、改环境变量、切目录✅ 测试结束全部还原tmp_pathdef test_xxx(tmp_path):每个测试独有的临时目录Path 对象✅ 默认保留最近 3 次运行capsysdef test_xxx(capsys):读取测试中 print 到 stdout/stderr 的内容✅ 结束后恢复原始流三者的共同哲学测试中做的所有破坏性操作都不应该泄漏到下一个测试。这正是 pytest 让新手写测试毫无心理负担的原因。monkeypatch如何安全打补丁而不污染环境monkeypatch是 pytest 最常被用到的内置 fixture它提供的是一组改完必还原的安全操作源码位于 src/_pytest/monkeypatch.py。官方文档的完整示例在 doc/en/how-to/monkeypatch.rst。一行代码替换函数monkeypatch.setattr最常见的场景被测代码依赖网络请求或用户目录测试时希望它返回固定值。只需把函数替换掉测试结束后 pytest 自动恢复原样def test_getssh(monkeypatch): monkeypatch.setattr(Path, home, lambda: Path(/abc)) assert getssh() Path(/abc/.ssh)setattr的签名见 src/_pytest/monkeypatch.py还支持直接传字符串目标如requests.sessions.Session.request无需 import 原模块。设置环境变量、删除字典项、切换目录常用方法作用源码位置setenv/delenv安全增删环境变量monkeypatch.py#L334setitem/delitem安全修改/删除字典项monkeypatch.py#L128syspath_prepend临时修改sys.pathmonkeypatch.py#L363chdir临时切换工作目录monkeypatch.py#L405小技巧删除可能不存在的东西时加raisingFalse例如monkeypatch.delenv(USER, raisingFalse)避免变量本来就不存在时误报 KeyError。monkeypatch 避坑三原则 ⚠️别打补丁到内置函数如open、compile可能破坏 pytest 自身优先打使用方而非源头若你的模块写了from os import getcwd应 patchmymodule.getcwd而不是os.getcwd用 context 限定作用域with monkeypatch.context() as m:可以把补丁限制在代码块内适合复杂 fixture见 monkeypatch.py#L149。tmp_path给每个测试一个独立临时目录测试中要写文件千万不要在源码目录里制造垃圾文件。tmp_path会自动提供一个pathlib.Path类型的临时目录且每个测试函数都是全新的、互不干扰的。定义见 src/_pytest/tmpdir.py#L286。def test_create_file(tmp_path): p tmp_path / hello.txt p.write_text(content, encodingutf-8) assert p.read_text(encodingutf-8) contenttmp_path 与 tmp_path_factory 怎么选单个测试用→ 直接用tmp_path最简单多个测试共享一份大文件如生成的测试图片→ 用会话级的 tmp_path_factory配合pytest.fixture(scopesession)只生成一次避免重复计算。临时目录在哪里会留多久默认结构为{系统临时目录}/pytest-of-{用户}/pytest-{序号}/{测试名}/pytest 会自动保留最近 3 次运行的目录方便测试失败时回查现场。想自定义位置可用--basetemp参数想调整保留策略可配置tmp_path_retention_count。详细规则见 doc/en/how-to/tmp_path.rst。 排错神器故意让最后一条断言失败pytest 输出中会显示tmp_path PosixPath(.../test_xxx0)直接找到磁盘上的真实目录检查残留文件。capsys在测试中拦截 print 输出想断言某函数会打印特定内容用capsys就能在测试内部直接读取被捕获的输出源码在 src/_pytest/capture.py#L1013。def test_myoutput(capsys): print(hello) captured capsys.readouterr() assert captured.out hello\nreadouterr 的快照机制readouterr()返回一个带out和err属性的命名元组并且是快照式的调用后缓冲区清空之后打印的内容要再调一次才能读到——这让先打印、再断言、再打印、再断言的分步验证成为可能。4个兄弟fixture按需选择fixture捕获层级返回类型适用场景capsysPython 的sys.stdoutstr一般 print 断言最常用capsysbinary同左bytes被测代码写二进制数据capfd操作系统文件描述符 1/2str需要捕获 C 扩展、子进程输出capfdbinary同左bytesfd 级 二进制另外测试中可以用with capsys.disabled():临时关闭捕获让输出直接打到终端调试命令行加-s则是全局关闭捕获。完整说明见 doc/en/how-to/capture-stdout-stderr.rst。实用技巧清单5条经验一次带走 ✅参数声明即注入三个 fixture 都不需要 import测试函数签名里写上名字就能用共享逻辑抽 fixturemonkeypatch常与自定义pytest.fixture组合把打补丁封装成mock_response这样的语义化 fixture失败现场可回查tmp_path保留最近 3 次运行结果断言失败时去磁盘看真实文件内容输出断言优先 capsys比解析 JUnit 报告或用 print 肉眼检查精确得多临时文件用完就完monkeypatch的改动、capsys的流恢复都由 pytest 自动处理测试函数里不用写一行还原代码。延伸阅读源码与官方文档入口资料路径monkeypatch 使用指南doc/en/how-to/monkeypatch.rsttmp_path 使用指南doc/en/how-to/tmp_path.rststdout/stderr 捕获指南doc/en/how-to/capture-stdout-stderr.rst全部 fixture API 参考doc/en/reference/fixtures.rstmonkeypatch 源码src/_pytest/monkeypatch.pytmp_path 源码src/_pytest/tmpdir.pycapsys 捕获源码src/_pytest/capture.py掌握monkeypatch、tmp_path与capsys这三个内置 fixture你就拥有了 pytest 日常测试中最核心的三件套改环境、造数据、验输出且全部自动善后——这就是 pytest 写小测试很简单扩展也很强 的最佳注脚。【免费下载链接】pytestThe pytest framework makes it easy to write small tests, yet scales to support complex functional testing项目地址: https://gitcode.com/GitHub_Trending/py/pytest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表