- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我的库有一个 contrib
extra,其中有依赖项(比如 requests
),我希望用户必须安装才能访问 CLI API,但是我在 CI 测试期间安装了 contrib extra 如何使用 pytest
's MonkeyPatch
在测试期间删除依赖项以确保我的检测是正确的?
例如,如果 contrib
extra 将另外安装 requests
,所以我希望用户必须这样做
$ python -m pip install mylib[contrib]
然后能够在命令行上有一个看起来像的 CLI API
$ mylib contrib myfunction
myfunction
使用 requests
依赖
# mylib/src/mylib/cli/contrib.py
import click
try:
import requests
except ModuleNotFoundError:
pass # should probably warn though, but this is just an example
# ...
@click.group(name="contrib")
def cli():
"""
Contrib experimental operations.
"""
@cli.command()
@click.argument("example", default="-")
def myfunction(example):
requests.get(example)
# ...
如何在我的 pytest
测试中模拟或 monkeypatch out requests
以确保用户会正确收到警告连同 ModuleNotFoundError
如果他们这样做了
$ python -m pip install mylib
$ mylib contrib myfunction
?在阅读了有关 pytest 标签的其他一些问题后,我认为我仍然不明白该怎么做,所以我在这里问。
最佳答案
我最终所做的是有效的,而且我已经确认这是一个合理的方法 thanks to Anthony Sottile , 是通过在 sys.modules
中将其设置为 None
然后重新加载模块来模拟不存在额外的依赖项(此处为 requests
) (s) 需要使用 requests
。我测试有一个实际的投诉,即 requests
不存在,无法使用 caplog
导入。
这是我目前正在使用的测试(名称已更改以匹配我在上述问题中的玩具示例问题)
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()
我应该注意到,这实际上是在 @Abhyudai's answer to "Test for import of optional dependencies in init.py with pytest: Python 3.5 /3.6 differs in behaviour" 中提倡的。 @hoefling 链接到上面(在我解决这个问题之后但在我开始发布之前发布)。
如果人们有兴趣在实际的图书馆中看到这个,c.f.以下两个 PR:
注意事项:Anthony Sottile 警告说
reload()
can be kinda iffy -- I'd be careful with it (things which have old references to the old module will live on, sometimes it can introduce new copies of singletons (doubletons? tripletons?)) -- I've tracked down many-a-test-pollution problems toreload()
因此,如果我实现更安全的替代方案,我将修改此答案。
关于python - 如何在 pytest 中使用 monkeypatch 或 mock 删除库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63865618/
我是一名优秀的程序员,十分优秀!