Issue #362: Only unconfigure if configured

`pytest_unconfigure` can be called even if `pytest_configure` was not.
In order to avoid errors during unconfigure only perform the unconfigure
if the configure was performed. Add a counter which is incremented
before configure to track the number of times pytest started
initialization so that the config is not popped early from the stack.
This commit is contained in:
Nate Clark 2023-10-23 10:52:29 -04:00
parent 5707669579
commit 825fcf804b
2 changed files with 31 additions and 2 deletions

View File

@ -21,6 +21,10 @@ if TYPE_CHECKING:
from .parser import Feature, Scenario, Step
# Counter to track how many times pytest initialization was started
_INIT_COUNT = 0
def pytest_addhooks(pluginmanager: PytestPluginManager) -> None:
"""Register plugin hooks."""
from pytest_bdd import hooks
@ -52,6 +56,8 @@ def _pytest_bdd_example() -> dict:
def pytest_addoption(parser: Parser) -> None:
"""Add pytest-bdd options."""
global _INIT_COUNT
_INIT_COUNT += 1
add_bdd_ini(parser)
cucumber_json.add_options(parser)
generation.add_options(parser)
@ -66,14 +72,19 @@ def add_bdd_ini(parser: Parser) -> None:
def pytest_configure(config: Config) -> None:
"""Configure all subplugins."""
CONFIG_STACK.append(config)
assert _INIT_COUNT == len(CONFIG_STACK)
cucumber_json.configure(config)
gherkin_terminal_reporter.configure(config)
def pytest_unconfigure(config: Config) -> None:
"""Unconfigure all subplugins."""
CONFIG_STACK.pop()
cucumber_json.unconfigure(config)
global _INIT_COUNT
assert len(CONFIG_STACK) <= _INIT_COUNT
if len(CONFIG_STACK) == _INIT_COUNT:
CONFIG_STACK.pop()
cucumber_json.unconfigure(config)
_INIT_COUNT -= 1
@pytest.hookimpl(hookwrapper=True)

View File

@ -135,3 +135,21 @@ def test_pytest_bdd_after_scenario_called_after_scenario(pytester):
assert scenario_1.name == "Scenario 1"
assert scenario_2.name == "Scenario 2"
def test_pytest_unconfigure_without_configure(pytester):
"""
Simulate a plugin forcing an exit during configuration before bdd is configured
https://github.com/pytest-dev/pytest-bdd/issues/362
"""
pytester.makeconftest(
"""
import pytest
def pytest_configure(config):
pytest.exit("Exit during configure", 0)
"""
)
result = pytester.runpytest()
assert result.ret == 0