allure-framework / allure-framework/allure-python

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

Ouverte
#881 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
theme:pytest
Langage dominant
Python
Étoiles
814
Forks
260
Métriques de merge des PR
Aucune PR mergée en 30 j

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

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Exécutez la reproduction de pytest.main() imbriqué depuis test/test_parent.py avec la configuration pytest indiquée et examinez le chemin de KeyError dans allure_commons/reporter.py, en particulier stop_after_fixture et l'appel du listener dans allure_pytest/listener.py. La tâche est terminée lorsque la session pytest parente se termine correctement, que le teardown de la fixture enfant ne produit aucun KeyError et que les résultats Allure ne dupliquent plus la fixture de teardown.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
testing
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
48/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.