Skip to content

Fixture teardown does not time out if test failed #196

Description

@timoffex

I was surprised to find that pytest-timeout only applies to fixture teardowns if the underlying test succeeds:

import time

import pytest


@pytest.fixture
def bad_fixture():
    yield
    print("In bad_fixture... sleeping")
    time.sleep(5)  # Should time out!
    print("Didn't time out!")


@pytest.mark.usefixtures("bad_fixture")
def test_timeout1():
    print("In test_timeout1... raising an error")
    raise ValueError


@pytest.mark.usefixtures("bad_fixture")
def test_timeout2():
    print("In test_timeout2...")

When running using pytest --timeout 1, the time.sleep(5) times out in test_timeout2 but runs for the full 5 seconds in test_timeout1.

I expected the fixture to time out in both, and I figure this might be a pytest detail I don't understand. I spent some time tracing through pytest and pytest-timeout code and didn't figure out the answer. For some reason, the pytest_timeout_cancel_timer hook runs at different stages depending on whether the test failed.

Is this a bug? Is there a way to make the timeout apply to fixtures regardless of test status?

As a side-question / request, I'd love if there was a way to make pytest-timeout interrupt at an interval after the timeout, to cancel slow teardown operations that might run after the initial timeout. I think I have some misbehaving fixtures with blocking teardowns, but I'm having trouble locating them. My CI terminates the test job when it hangs, and because I'm using pytest-xdist, it's hard to figure out where a test worker was blocked (print statements don't propagate).

EDIT:

  • pytest version 8.4.2, also tested 9.1.1
  • pytest-timeout version 2.4.0
  • Running on macOS
  • Using the "signal" method

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions