allure-framework / allure-framework/allure-python
KeyError in allure_pytest when running pytest.main() from inside a test (nested pytest run)
- 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