-
Notifications
You must be signed in to change notification settings - Fork 255
Description
Running a nested pytest session (subsession) from within a test using pytest.main() causes allure to fail during teardown in subsession with a KeyError in allure_commons/reporter.py.
The inner test passes, but allure raises an exception, causing the overall main test to fail.
The issue reproduces only when both main and sub sessions use allure (for example, via configuration (pytest.ini or pyproject.toml) and the subsession runs teardown fixtures.
The report shows the subtest as broken and duplicates teardown fixtures for it - one fixture has passed state, and the duplicate has unknown state.
| simple_fixture::0 | Unknown |
|---|---|
| simple_fixture::0 | 0s |
Overriding alluredir doesn't help - allure report for main session always contains both tests, allure report for subsession - only its test.
Steps to reproduce:
- Set pytest ini options (I'm using
pyproject.toml)
[tool.pytest.ini_options]
addopts = [
"-v",
"--alluredir", "allure-results",
]- Create test file
from pathlib import Path
import pytest
def test_parent():
args: list[str] = [
f"{Path(__file__)}::test_child",
]
result = pytest.main(args)
assert not result
@pytest.fixture()
def simple_fixture():
yield 2
def test_child(simple_fixture):
assert simple_fixture == 2- Run the command
pytest test/test_parent.py::test_parentActual result:
❯ poetry run pytest test/test_parent.py::test_parent
======================================== test session starts =========================================
platform darwin -- Python 3.13.5, pytest-8.4.0, pluggy-1.6.0 -- /example_dir/Library/Caches/pypoetry/virtualenvs/tests_repo-CJ2ygyH8-py3.13/bin/python
cachedir: .pytest_cache
rootdir: /example_dir/tests_repo
configfile: pyproject.toml
plugins: allure-pytest-2.14.2, xdist-3.7.0, instafail-0.5.0, anyio-4.9.0, timeout-2.4.0, check-2.5.3, mock-3.14.1, cov-6.1.1
collected 1 item
test/test_parent.py::test_parent FAILED [100%]
============================================== FAILURES ==============================================
____________________________________________ test_parent _____________________________________________
def test_parent():
args: list[str] = [
"-s",
f"{Path(__file__)}::test_child",
]
result = pytest.main(args)
> assert not result
E assert not <ExitCode.TESTS_FAILED: 1>
test/test_parent.py:12: AssertionError
---------------------------------------- Captured stdout call ----------------------------------------
============================= test session starts ==============================
platform darwin -- Python 3.13.5, pytest-8.4.0, pluggy-1.6.0 -- /example_dir/Library/Caches/pypoetry/virtualenvs/tests_repo-CJ2ygyH8-py3.13/bin/python
cachedir: .pytest_cache
rootdir: /example_dir/tests_repo
configfile: pyproject.toml
plugins: allure-pytest-2.14.2, xdist-3.7.0, instafail-0.5.0, anyio-4.9.0, timeout-2.4.0, check-2.5.3, mock-3.14.1, cov-6.1.1
collecting ... collected 1 item
test/test_parent.py::test_child PASSED
test/test_parent.py::test_child ERROR
==================================== ERRORS ====================================
_______________________ ERROR at teardown of test_child ________________________
self = <allure_commons._allure.fixture object at 0x1027574d0>, args = ()
kwargs = {}
def __call__(self, *args, **kwargs):
self.parameters = func_parameters(self._fixture_function, *args, **kwargs)
> with self:
^^^^
../../Library/Caches/pypoetry/virtualenvs/tests_repo-CJ2ygyH8-py3.13/lib/python3.13/site-packages/allure_commons/_allure.py:230:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../Library/Caches/pypoetry/virtualenvs/tests_repo-CJ2ygyH8-py3.13/lib/python3.13/site-packages/allure_commons/_allure.py:240: in __exit__
plugin_manager.hook.stop_fixture(parent_uuid=self._parent_uuid,
../../Library/Caches/pypoetry/virtualenvs/tests_repo-CJ2ygyH8-py3.13/lib/python3.13/site-packages/allure_pytest/listener.py:66: in stop_fixture
self.allure_logger.stop_after_fixture(uuid,
../../Library/Caches/pypoetry/virtualenvs/tests_repo-CJ2ygyH8-py3.13/lib/python3.13/site-packages/allure_commons/reporter.py:109: in stop_after_fixture
self._update_item(uuid, **kwargs)
../../Library/Caches/pypoetry/virtualenvs/tests_repo-CJ2ygyH8-py3.13/lib/python3.13/site-packages/allure_commons/reporter.py:62: in _update_item
item = self._items[uuid] if uuid else self._items[next(reversed(self._items))]
^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <allure_commons.reporter.ThreadContextItems object at 0x10264b4d0>
item = '5073499a-d95d-40a6-a635-36507b26b451'
def __getitem__(self, item):
> return self.thread_context.__getitem__(item)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E KeyError: '5073499a-d95d-40a6-a635-36507b26b451'
../../Library/Caches/pypoetry/virtualenvs/tests_repo-CJ2ygyH8-py3.13/lib/python3.13/site-packages/allure_commons/reporter.py:33: KeyError
=========================== short test summary info ============================
ERROR test/test_parent.py::test_child - KeyError: '5073499a-d95d-40a6-a635-36...
========================== 1 passed, 1 error in 0.05s ==========================
====================================== short test summary info =======================================
FAILED test/test_parent.py::test_parent - assert not <ExitCode.TESTS_FAILED: 1>
========================================= 1 failed in 0.14s ==========================================