Skip to content

KeyError in allure_pytest when running pytest.main() from inside a test (nested pytest run) #881

@sashko1988

Description

@sashko1988

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:

  1. Set pytest ini options (I'm using pyproject.toml)
[tool.pytest.ini_options]
addopts = [
    "-v",
    "--alluredir", "allure-results",
]
  1. 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
  1. Run the command
pytest test/test_parent.py::test_parent

Actual 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 ==========================================

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions