【发布时间】:2021-09-24 08:36:05
【问题描述】:
上下文是我正在尝试对一些涉及正在检查的 Python 版本的 Python 代码进行单元测试。我在platform 方法下工作,但有人告诉我使用platform 不是一个好主意,我应该改用sys.version_info。因此我有以下逻辑:
def main() -> None:
python_version = f"{sys.version_info[0]}.{sys.version_info[1]}"
if float(python_version) < 3.7:
sys.stderr.write("\nQuendor requires Python 3.7 or later.\n")
sys.stderr.write(f"Your current version is {python_version}\n\n")
sys.exit(1)
(我确实意识到我也可以为我的支票使用if sys.version_info < (3, 7):。)
我的单元测试是这样的:
def test_bad_python_version(capsys) -> None:
import sys
from quendor.__main__ import main
with mock.patch.object(sys, "version_info") as v_info:
v_info.major = 3
v_info.minor = 5
main()
terminal_text = capsys.readouterr()
print(terminal_text)
当然,我的测试还没有完成。我正在尝试打印输出以确保测试正常工作。
运行该测试让我知道:
ValueError: could not convert string to float:
"<MagicMock name='version_info.__getitem__()'
id='1417904973808'>.<MagicMock name='version_info.__getitem__()'
id='1417904973808'>"
顺便说一句,如果我将 main 中的条件切换到此 (if sys.version_info < (3, 7):),我会收到类似但不同的错误:
TypeError: '<' not supported between instances of 'MagicMock' and 'tuple'
我不确定如何正确传递 version_info,我认为这是我的问题。我已经搜索了文档,并且在这里看到了关于 MagicMock 的其他问题(例如:How to unit test a python version switch),但没有明确说明:“这就是如何做到这一点。”
我应该注意到,在使用 platform 时,我的版本运行良好。我的那个版本的测试看起来像这样:
with mock.patch.object(
platform,
"python_version",
return_value="3.5",
), pytest.raises(SystemExit) as pytest_wrapped_e:
main()
terminal_text = capsys.readouterr()
expect(terminal_text.err).to(contain("Quendor requires Python 3.7"))
关键似乎是我使用的“return_value”。
【问题讨论】:
标签: python pytest python-unittest