Skip to content

regression in pytest 8.1.1: module level setup function doesn't seem to be run #12113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
4 tasks done
neutrinoceros opened this issue Mar 12, 2024 · 6 comments
Closed
4 tasks done

Comments

@neutrinoceros
Copy link
Contributor

neutrinoceros commented Mar 12, 2024

The following is a minimal reproducer for a real-life application in yt:

# test.py
obj = None
def setup():
    global obj
    obj = []

def test_foo():
    assert len(obj) == 0

This test worked as expected until pytest 8.0.2 but fails with version 8.1.1 as

=========================== test session starts ===========================
platform darwin -- Python 3.12.2, pytest-8.1.1, pluggy-1.4.0
rootdir: /private/tmp
collected 1 item

test.py F                                                           [100%]

================================ FAILURES =================================
________________________________ test_foo _________________________________

    def test_foo():
>       assert len(obj) == 0
E       TypeError: object of type 'NoneType' has no len()

test.py:7: TypeError
========================= short test summary info =========================
FAILED test.py::test_foo - TypeError: object of type 'NoneType' has no len()
============================ 1 failed in 0.01s ===========================

which seems to indicate that the setup function wasn't run ahead of the test.
Possibly related to #12011 or how it was resolved ?

exact env:

Package   Version
--------- -------
iniconfig 2.0.0
packaging 24.0
pluggy    1.4.0
pytest    8.1.1

Bug seen on MacOS 14 and ubuntu-latest on GHA

  • a detailed description of the bug or problem you are having
  • output of pip list from the virtual environment you are using
  • pytest and operating system versions
  • minimal example if possible
@bluetech
Copy link
Member

setup was part of nose compatibility which is removed in pytest 8: https://docs.pytest.org/en/stable/deprecations.html#support-for-tests-written-for-nose

Use setup_module instead.

@neutrinoceros
Copy link
Contributor Author

Oh, so the bug is that it still worked in pytest 8.0.x, is that it ?

@neutrinoceros
Copy link
Contributor Author

I would expect that changing def setup() -> def setup_module() wouldn't change how pytest behaves at all, but this doesn't seem to be the case: I'm actually seeing a bunch of surprising failures when I do just that (see https://github.com/yt-project/yt/pull/4852/checks). Admittedly, our test suite is too complex to easily analyse and I wouldn't be surprise if what we're seeing here was a symptom of test pollution, but I'm still surprised that this wasn't visible before. Any clue ?

@bluetech
Copy link
Member

I would expect that changing def setup() -> def setup_module() wouldn't change how pytest behaves at all

This is the expectation.

I tried to take a look but the project is quite formidable so I can't quickly figure out what's going wrong.

Is it possible that the breakage is from upgrading to pytest 8 and not necessarily from setup -> setup_module? One way to check this is to do the setup_module change with the pytest<8 pin and see what happens (setup_module is not a new thing so this is fully backward compatible).

@neutrinoceros
Copy link
Contributor Author

I tried to take a look but the project is quite formidable so I can't quickly figure out what's going wrong.

yeah we have a lot of technical debt. Thanks for taking a shot still :)

Is it possible that the breakage is from upgrading to pytest 8 and not necessarily from setup -> setup_module? One way to check this is to do the setup_module change with the pytest<8 pin and see what happens (setup_module is not a new thing so this is fully backward compatible).

I'll try that !

@neutrinoceros
Copy link
Contributor Author

So actually what happened is that I forgot to also migrate def teardown() -> def teardown_module(). Everything looks good now so I think we can just close this. Thanks @bluetech for your feedback !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants