重构Pytest测试代码以解决flake8-pytest-style的PT012告警(避免raises语句中包含过多逻辑)
Fixing PT012: Simplify Logic Inside
pytest.raises() Let's break down how to fix this PT012 violation without sacrificing readability or resorting to helper functions. The rule's core intent is to keep the code inside pytest.raises() focused only on the action that triggers the exception—all setup work should live outside the context manager.
Here's your refactored test code:
def test_bad_python_version(capsys) -> None: import platform from quendor.__main__ import main # Move mock setup OUTSIDE the pytest.raises() context with mock.patch.object(platform, "python_version") as v_info: v_info.return_value = "3.5" # Now pytest.raises() only contains the code that triggers the exception 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))
What changed and why it works:
- We split the nested
withstatements: first handle the mock setup in its own context, then wrap only themain()call inpytest.raises(). - This keeps the
pytest.raises()block minimal (just the line that triggers theSystemExit), which directly addresses the PT012 rule. - Readability stays high: all setup logic is grouped at the start of the test, and the exception-triggering action is clearly isolated.
Why this is better than other workarounds:
- No need to disable the rule (you keep the benefit of linting for clean test code).
- No helper functions required—you don't have to jump around files to understand the test flow.
- The test's intent is even clearer now: setup the mock, run the code that should fail, then verify the outcomes.
This aligns with pytest's best practices: keeping exception-focused tests tight and separating setup from the actual exception trigger.
内容的提问来源于stack exchange,提问作者Jeff Nyman
相关产品推荐
相关产品推荐

