在Pytest中重构测试逻辑以避免复杂的raise块



我使用的是flake8-pytest-style插件,它将某个测试标记为违反PT012。这是关于在raises()语句中有太多的逻辑。

所讨论的代码是:

def test_bad_python_version(capsys) -> None:
import platform
from quendor.__main__ import main
with pytest.raises(SystemExit) as pytest_wrapped_e, mock.patch.object(
platform,
"python_version",
) as v_info:
v_info.return_value = "3.5"
main()
terminal_text = capsys.readouterr()
expect(terminal_text.err).to(contain("Quendor requires Python 3.7"))
expect(pytest_wrapped_e.type).to(equal(SystemExit))
expect(pytest_wrapped_e.value.code).to(equal(1))
基本上,这是测试以下代码:
def main() -> int:
if platform.python_version() < "3.7":
sys.stderr.write("nQuendor requires Python 3.7 or later.n")
sys.stderr.write(f"Your current version is {platform.python_version()}nn")
sys.exit(1)

我所做的就是传入一个小于要求的Python版本,并确保错误按预期出现。测试本身工作得很好。(我意识到这是否应该是一个单元测试是值得怀疑的,因为它实际上是在测试Python的一个方面,而不是我自己的代码。)

显然,lint检查表明我的测试有点混乱,我当然可以理解。但是从上面引用的页面上看,我不清楚我应该怎么做。

我确实意识到我可以为这个特定的测试禁用质量检查,但我正在努力编写尽可能好的Python代码,特别是在测试方面。我不知道如何重构这段代码以满足标准。

我知道我可以创建一些其他测试辅助函数,然后从raises块调用该函数。但这让我觉得总体上不太清楚,因为现在你必须看两个地方才能看到测试正在做什么。

这个lint错误是很好的一个!事实上,在您的情况下,因为没有遵循lint错误,您有两行不可达的代码(!)(两个capsys相关的行),因为main()总是引发

lint建议您raises()中只有一行——从现有代码中进行的天真重构是:

with mock.patch.object(
platform,
"python_version",
return_value="3.5",
):
with pytest.raises(SystemExit) as pytest_wrapped_e:
main()
terminal_text = capsys.readouterr()
expect(terminal_text.err).to(contain("Quendor requires Python 3.7"))
expect(pytest_wrapped_e.type).to(equal(SystemExit))
expect(pytest_wrapped_e.value.code).to(equal(1))
顺便说一句,你永远不应该使用platform.python_version()来进行版本比较,因为它会在python 3.10中产生不正确的结果——更多关于它的信息,在这里

相关内容

  • 没有找到相关文章