Mat*_*ert 6 python monkeypatching pytest pytest-mock
如果我的库中有一个contrib附加程序,其中包含依赖项(例如requests),我希望用户必须安装该附加程序才能访问 CLI API,但我在 CI 测试期间安装了 contrib 附加程序,我如何使用pytest来MonkeyPatch删除测试期间的依赖关系以确保我的检测正确?
例如,如果contrib额外的内容会另外安装requests,那么我希望用户必须这样做
$ python -m pip install mylib[contrib]
Run Code Online (Sandbox Code Playgroud)
然后能够在命令行上使用 CLI API,如下所示
$ mylib contrib myfunction
Run Code Online (Sandbox Code Playgroud)
wheremyfunction使用requests依赖项
$ python -m pip install mylib[contrib]
Run Code Online (Sandbox Code Playgroud)
我如何在测试中模拟或猴子补丁 ,以便我可以确保用户正确地收到警告以及如果他们这样做requestspytestModuleNotFoundError
$ python -m pip install mylib
$ mylib contrib myfunction
Run Code Online (Sandbox Code Playgroud)
?在阅读了有关 pytest 标签的其他一些问题后,我仍然认为我不明白如何做到这一点,所以我在这里问。
我最终所做的工作是有效的,并且我已经确认这是一个合理的方法,感谢 Anthony Sottile,就是通过将其设置为in然后重新加载模块来模拟额外的依赖项(此处requests)不存在。需要使用. 我测试了是否有一个实际的投诉不存在可以通过使用导入。Nonesys.modulesrequestsrequestscaplog
这是我当前正在使用的测试(名称已更改以匹配上面问题中的玩具示例问题)
import mylib
import sys
import logging
import pytest
from unittest import mock
from importlib import reload
from importlib import import_module
# ...
def test_missing_contrib_extra(caplog):
with mock.patch.dict(sys.modules):
sys.modules["requests"] = None
if "mylib.contrib.utils" in sys.modules:
reload(sys.modules["mylib.contrib.utils"])
else:
import_module("mylib.cli")
with caplog.at_level(logging.ERROR):
# The 2nd and 3rd lines check for an error message that mylib throws
for line in [
"import of requests halted; None in sys.modules",
"Installation of the contrib extra is required to use mylib.contrib.utils.download",
"Please install with: python -m pip install mylib[contrib]",
]:
assert line in caplog.text
caplog.clear()
Run Code Online (Sandbox Code Playgroud)
我应该注意到,这实际上是在@Abhyudai 对“使用 pytest 在init .py 中导入可选依赖项进行测试:Python 3.5 /3.6 行为不同”的回答中提倡的,@hoefling 链接到上面(在我解决了这个问题之后发布,但是在我开始发布这个之前)。
如果人们有兴趣在实际的图书馆中看到这一点,请参阅以下两个 PR:
注:安东尼·索蒂尔警告说
reload()可能有点不确定 - 我会小心它(对旧模块有旧引用的东西将继续存在,有时它可以引入单例的新副本(双例?三例?)) - 我已经追踪到了很多-a-测试污染问题reload()
所以如果我实施一个更安全的替代方案,我会修改这个答案。
| 归档时间: |
|
| 查看次数: |
1484 次 |
| 最近记录: |