allure-framework / allure-framework/allure-python

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

Open
#881 0 comments 0 reactions 0 assignees View on GitHub
theme:pytest
Dominant language
Python
Stars
814
Forks
260
PR merge metrics
No merged PRs in 30d

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:
1. Set pytest ini options (I'm using `pyproject.toml`)
```toml
[tool.pytest.ini_options]
addopts = [
"-v",
"--alluredir", "allure-results",
]
```
2. Create test file

```python
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

```
3. Run the command
```bash
pytest test/test_parent.py::test_parent
```

Actual result:
```log
❯ 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

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 = , 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 =
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
========================================= 1 failed in 0.14s ==========================================
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.