Why is `pytest_sessionfinish` not getting invoked when running tests in pytest?

While running pytest, the pytest_sessionfinish hook isn’t being called even though it’s defined in the same test file.

The goal is to capture the number of passed and failed tests and send them to a Prometheus gateway once the session ends.

However, the hook never executes regardless of flags or environments.

Example code:

import pytest

@pytest.fixture(scope="session")
def my_fixture():
    print("in fun")
    yield

def test_example(my_fixture):
    assert 2 + 2 == 4

@pytest.hookimpl(tryfirst=True)
def pytest_sessionfinish(session, exitstatus):
    print("pytest_sessionfinish called")

Attempts made:

  • Used -s and -v flags to ensure print outputs aren’t suppressed.
  • Enabled debug logging to check for errors.
  • Tried on multiple environments with the same result.

pytest_sessionfinish won’t be triggered if it’s defined inside a test file. It must be placed in a plugin or conftest.py file since pytest only recognizes hook implementations from those locations.

Moving the hook to conftest.py will allow pytest to call it after all tests complete.

I ran into this exact issue before.

The problem is that pytest_sessionfinish hooks won’t be triggered if they’re defined inside a test file.

Pytest only recognizes hooks in plugins or conftest.py files.

I fixed it by moving the hook to conftest.py, and then it ran perfectly after the test session ended.

@sndhu.rani I struggled with this too.

The key thing to remember is that hooks like pytest_sessionfinish are only picked up from conftest.py or plugins, not from the test files themselves.

Moving your hook out of the test file ensures it fires after all tests, which is perfect if you want to send metrics or cleanup actions at session end.

From my experience, pytest_sessionfinish is a session-level hook, so defining it in a test file won’t work, pytest ignores it there.

To get it invoked, create a conftest.py in your test folder and put your hook there:

# conftest.py
import pytest

@pytest.hookimpl(tryfirst=True)
def pytest_sessionfinish(session, exitstatus):
    print("pytest_sessionfinish called")

Once I did that, it consistently executed at the end of the test run.