Skip to content

Order of fixtures and hooks changes depending on if there's one or more tests  #7484

Open
@eplodn

Description

@eplodn
  • [ V ] a detailed description of the bug or suggestion
    I have an autouse fixture and use pytest_sessionfinish hook.
    I use a -k flag to run a subset of tests.
    I use a -x flag to end after first failure.
    The order of the execution of fixture and hook depends on whether one or more tests were collected.

  • [ V ] output of pip list from the virtual environment you are using

------------------ -------
attrs              19.3.0
importlib-metadata 1.7.0
more-itertools     8.4.0
packaging          20.4
pip                20.1.1
pluggy             0.13.1
py                 1.9.0
pyparsing          2.4.7
pytest             5.4.3
setuptools         47.1.1
six                1.15.0
wcwidth            0.2.5
wheel              0.34.2
zipp               3.1.0
  • [ V ] pytest and operating system versions
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
  • [ V ] minimal example if possible
$ mkdir hooks_and_fixtures
$ cd hooks_and_fixtures
$ python3.6 -m virtualenv myvirtualenv
$ source myvirtualenv/bin/activate
$ python3.6 -m pip install pytest
$ mkdir tests
$ cat > tests/test_something.py <<EOF
def test_something():
    assert False
EOF
$ cat > tests/test_something_else.py <<EOF
def test_something_else():
    assert True
EOF
$ cat > conftest.py <<EOF
import pytest

def pytest_sessionfinish(session, exitstatus):
    print("Now in pytest_sessionfinish", flush=True)

@pytest.fixture(scope='session', autouse=True)
def env(request):
    print("Now before yield", flush=True)
    yield
    print("Now after yield", flush=True)
EOF

Now let's run the two tests:

$ python3.6 -m pytest -x --color=yes --tb=long -ra --capture=sys --capture=fd  --show-capture=no -v -s tests -k "something"
=======
collected 2 items

tests/test_something.py::test_something Now before yield
FAILED Now in pytest_sessionfinish
Now after yield
=======

As can be seen, the order is: before yield -> pytest_sessionfinish > after yield.

Now let's rename one of the tests so only one remains, and run it:

$ mv tests/test_something_else.py tests/test_something_else.not_py 

$ python3.6 -m pytest -x --color=yes --tb=long -ra --capture=sys --capture=fd  --show-capture=no -v -s tests -k "something"
======
collected 1 item

tests/test_something.py::test_something Now before yield
FAILEDNow after yield
Now in pytest_sessionfinish
======

Here the order is different: before yield -> after yield > pytest_sessionfinish.

As my "after yield" code is bringing some data that my "pytest_sessionfinish" needs, I really need a predictable order.

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: selectionrelated to test selection from the command linetype: bugproblem that needs to be addressed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions