allure-framework / allure-python

Allure integrations for Python test frameworks
https://allurereport.org/
Apache License 2.0
713 stars 233 forks source link

[BUG] Latest pytest release (8.1.0) breaks allure_listener plugin #794

Closed mihhail-m closed 4 months ago

mihhail-m commented 4 months ago

[//]: # ( . Note: for support questions, please use Stackoverflow or Gitter. . This repository's issues are reserved for feature requests and bug reports. . . In case of any problems with Allure Jenkins plugin please use the following repository . to create an issue: https://github.com/jenkinsci/allure-plugin/issues . . Make sure you have a clear name for your issue. The name should start with a capital . letter and no dot is required in the end of the sentence. An example of good issue names: . . - The report is broken in IE11 . - Add an ability to disable default plugins . - Support emoji in test descriptions )

I'm submitting a ...

What is the current behavior?

After pytest released its latest version 8.1.0 it suddenly started to break allure_listener plugin on fixtures initilization/teardown thus preventing from running any tests with pytest and allure-pytest installed.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem

  1. Have pytest=8.1.0 installed
  2. Have allure-pytest installed (as of the moment of writing it is 2.13.0)
  3. Have simple project with pytest configured
  4. Have fixtures defined with @pytest.fixture decorator

The following is a minimal example the I could reproduce from our tests that caught this issue:

# conftest.py
import pytest

class MyBaseTestClass:
   def __init__(self, val):
       self.val = val

@pytest.fixture
def my_fixture():
    yield MyBaseTestClass("some value")
# test_example.py
def test_my_fixture(my_fixture):
    assert my_fixture.val == "some value"

What is the expected behavior?

It is expected for allure-pytest not to break whole project when updating to pytest==8.1.0

What is the motivation / use case for changing the behavior?

Not to break tests

Please tell us about your environment:

Other information

When running the test the stack trace gives the following error:

self = <allure_pytest.listener.AllureListener object at 0x1378f7250>, item = <Function test_create_enum_metadata[options_bounds0]>

    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_setup(self, item):
        if not self._cache.get(item.nodeid):
            uuid = self._cache.push(item.nodeid)
            test_result = TestResult(name=item.name, uuid=uuid, start=now(), stop=now())
            self.allure_logger.schedule_test(uuid, test_result)
        yield
>       self._update_fixtures_children(item)

.nox/tests-3-10/lib/python3.10/site-packages/allure_pytest/listener.py:102: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.nox/tests-3-10/lib/python3.10/site-packages/allure_pytest/listener.py:71: in _update_fixtures_children
    for fixturedef in _test_fixtures(item):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

item = <Function test_create_enum_metadata[options_bounds0]>

    def _test_fixtures(item):
        fixturemanager = item.session._fixturemanager
        fixturedefs = []

        if hasattr(item, "_request") and hasattr(item._request, "fixturenames"):
            for name in item._request.fixturenames:
>               fixturedefs_pytest = fixturemanager.getfixturedefs(name, item.nodeid)
E               AttributeError: 'str' object has no attribute 'iter_parents'

.nox/tests-3-10/lib/python3.10/site-packages/allure_pytest/listener.py:345: AttributeError

As it can be seen from the error message the following line is causing the issue: https://github.com/allure-framework/allure-python/blob/058a6afb0601f790162f058b3c1d3e7300d420ab/allure-pytest/src/listener.py#L102

I believe this can be due to following change recently introduced in the pytest framework, because right after that, we upgraded to the latest pytest and our tests started to fail without even running (the error thrown during the initialization of the fixtures I believe). And downgrading to pytest==8.0.0 fixed this issues. However, I think, it would be nice to fix this to make sure further compatability between allure-pytest and pytest framework.

Commit from the pytest: https://github.com/pytest-dev/pytest/commit/434282e17f5f1f4fcc1464a0a0921cf19804bdd7

P.S I am not exactly sure who should be responsible for handling this issue whether allure team or pytest team.

[//]: # ( . e.g. detailed explanation, stacktraces, related issues, suggestions . how to fix, links for us to have more context, eg. Stackoverflow, Gitter etc )

zheldashev commented 4 months ago

pytest team send me to allure-pytest team https://github.com/pytest-dev/pytest/issues/12063

nicoddemus commented 4 months ago

This is the related change:

https://docs.pytest.org/en/stable/changelog.html#trivial-internal-changes

So it should a matter of changing:

fixturedefs_pytest = fixturemanager.getfixturedefs(name, item.nodeid)

To:

fixturedefs_pytest = fixturemanager.getfixturedefs(name, item)
fenchu commented 4 months ago

Our CI/CD pipeline fails with pytest==8.1.0. removing --alluredir and it works again, but without allure https://github.com/pytest-dev/pytest/issues/12078

delatrie commented 4 months ago

@fenchu pytest 8.1.0 has been yanked. Roll back to 8.0.2 until they come up with a new one.

dongfangtianyu commented 4 months ago

pytest 已经发布新的版本 8.1.1。于是重新引发allure-pytest插件内的错误

EN Pytest has released a new version 8.1.1. So it re triggered the error within the allure-pytest plugin

delatrie commented 4 months ago

The fix is included in allure-pytest 2.13.3

jiangxuhui commented 2 months ago

So,guys! my project have very similar question.

# requirements.txt
pytest==8.1.1
allure-pytest==2.8.6
...

when i follow nicoddemus, it works! but I don't thinks is a good idea, so should I upgrade pytest or allure-pytest to what version?

listener.py line 279
    if hasattr(item, "fixturenames"):
        for name in item.fixturenames:
            # origin 
            # fixturedef = fixturemanager.getfixturedefs(name, item.nodeid)

            # modify
            fixturedef = fixturemanager.getfixturedefs(name, item)
            if fixturedef:
                fixturedefs.append(fixturedef[-1])

    return fixturedefs

I just have upgraded pytest version from 8.1.1 to 8.2.0, allure-pytest version from 2.8.6 to 2.8.13, the question is fixed. thanks