Skip to content

Conversation

@FazeelUsmani
Copy link

Fixes #8375

When a session-scoped autouse fixture raises an exception during teardown, and the last test in the suite is marked @pytest.mark.xfail, pytest was incorrectly showing an extra XFAIL line (duplicated) instead of reporting the teardown failure as an ERROR.

Problem

Before this fix:

  • Output: 1 passed, 2 xfailed (incorrect - duplicate xfail)
  • Session fixture teardown exceptions were being treated as expected test failures

After this fix:

  • Output: 1 passed, 1 xfailed, 1 error (correct)
  • Session fixture teardown exceptions are properly reported as errors

Root Cause

The xfail handling in pytest_runtest_makereport was being applied to all test phases (setup, call, teardown). This caused any exception during teardown to be converted to an xfail result if the test was marked with @pytest.mark.xfail.

Solution

Restrict xfail handling to only apply during the "call" phase. Setup and teardown failures are now properly reported as errors, regardless of xfail markers on the test.

This aligns with the principle that xfail should only apply to test execution logic, not to fixture infrastructure failures (setup/teardown).

Changes

  • Modified src/_pytest/skipping.py: Added if call.when == "call" condition to xfail handling
  • Added regression test: test_session_fixture_teardown_exception_with_xfail
  • Updated existing tests to expect correct behavior (errors instead of xfails for setup/teardown failures)

Fazeel Usmani and others added 2 commits November 7, 2025 14:39
…FAILs

When a session-scoped autouse fixture raises an exception during teardown,
and the last test in the suite is marked @pytest.mark.xfail, pytest was
incorrectly showing an extra XFAIL line (duplicated) instead of reporting
the teardown failure as an ERROR.

The root cause was that the xfail handling in pytest_runtest_makereport was
being applied to all phases (setup, call, teardown), converting any exception
into an xfail result if the test was marked with xfail. This meant that
session fixture teardown exceptions were being misreported as expected failures.

The fix restricts xfail handling to only apply during the "call" phase.
Setup and teardown failures are now properly reported as errors, regardless
of xfail markers on the test. This aligns with the principle that xfail
should only apply to test execution, not to fixture setup/teardown failures.

Fixes pytest-dev#8375
@FazeelUsmani FazeelUsmani deleted the claude/update-commit-author-011CUth8nk5b4ZT9xscUXzwv branch November 7, 2025 15:07
@FazeelUsmani FazeelUsmani restored the claude/update-commit-author-011CUth8nk5b4ZT9xscUXzwv branch November 7, 2025 15:09
@FazeelUsmani FazeelUsmani reopened this Nov 7, 2025
@FazeelUsmani FazeelUsmani marked this pull request as draft November 7, 2025 16:06
rep.wasxfail = call.excinfo.value.msg
rep.outcome = "skipped"
elif not rep.skipped and xfailed:
if call.excinfo:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have an if here already, so you can just combine this to

Suggested change
if call.excinfo:
if call.excinfo and call.when == "call":

instead of having to indent everything under a second if.

Even if a test is marked xfail, if the setup fails, that's an
infrastructure error, not an expected test failure.
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a major behavior change, which probably warrants some more discussions (and possibly a major release, might be too late for 9.0.0 though).

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

Successfully merging this pull request may close these issues.

Error not raised in session fixture when mark.xfail is set on last test

2 participants