pytest error vs failure, ERROR at setup/teardown (tested)

In pytest, FAILED means the test function itself raised (an assert or any exception), while ERROR means a fixture raised, either before the test (ERROR at setup of test_x, the test never ran) or after it (ERROR at teardown). Look at the fixtures, not the test.

1. One file with every outcome

import pytest


@pytest.fixture
def db():
    raise ConnectionError("database not reachable")     # fails in setup
    yield


@pytest.fixture
def tmpfile():
    yield "data.txt"
    raise PermissionError("could not delete data.txt")  # fails in teardown


def test_assert():
    assert 1 + 1 == 3                  # FAILED: the test's own assertion


def test_exception_in_test():
    {}["missing"]                       # FAILED too: any exception inside the test body


def test_uses_db(db):
    pass                                # ERROR at setup: the test never ran


def test_uses_tmpfile(tmpfile):
    pass                                # PASSED, then ERROR at teardown


def test_missing_fixture(dbb):
    pass                                # ERROR at setup: fixture 'dbb' not found

Run with -rA (summary line for every test) and filtered to the headers and E lines:

$ pytest -rA test_ef.py | grep -E "^(PASSED|FAILED|ERROR)|^E  |=====|^_"
============================= test session starts ==============================
==================================== ERRORS ====================================
________________________ ERROR at setup of test_uses_db ________________________
E       ConnectionError: database not reachable
____________________ ERROR at teardown of test_uses_tmpfile ____________________
E       PermissionError: could not delete data.txt
____________________ ERROR at setup of test_missing_fixture ____________________
E       fixture 'dbb' not found
=================================== FAILURES ===================================
_________________________________ test_assert __________________________________
E       assert (1 + 1) == 3
____________________________ test_exception_in_test ____________________________
E       KeyError: 'missing'
==================================== PASSES ====================================
=========================== short test summary info ============================
PASSED test_ef.py::test_uses_tmpfile
ERROR test_ef.py::test_uses_db - ConnectionError: database not reachable
ERROR test_ef.py::test_uses_tmpfile - PermissionError: could not delete data.txt
ERROR test_ef.py::test_missing_fixture
FAILED test_ef.py::test_assert - assert (1 + 1) == 3
FAILED test_ef.py::test_exception_in_test - KeyError: 'missing'
==================== 2 failed, 1 passed, 3 errors in 0.03s =====================
(exit code of pytest:)
1

2. Error vs failure

So "ERROR at setup of test_x" means: look at the fixtures test_x uses, not at the test. Here db raised ConnectionError before its yield.

3. A test can pass and error at the same time

test_uses_tmpfile appears twice in the summary: PASSED, then ERROR for the teardown, and it is counted in both totals (2 failed, 1 passed, 3 errors from 5 tests). The code after yield in a fixture runs after the test; an exception there is reported as "ERROR at teardown of ...". Errors and failures both make pytest exit with code 1.

4. Fixing setup and teardown errors

Related: pytest ERROR collecting: ModuleNotFoundError, pytest no tests ran (exit code 5).

Frequently asked questions

What is the difference between error and failure in pytest?

FAILED: an assertion or exception inside the test function. ERROR: an exception in a fixture during setup or teardown, or a missing fixture.

What does ERROR at setup of mean in pytest?

A fixture used by the test raised before the test ran (or the fixture name was not found), so the test itself never executed.

Can a pytest test both pass and error?

Yes: if the test passes but a fixture's teardown (code after yield) raises, pytest reports PASSED and ERROR at teardown for the same test.

Written with AI assistance. Measured on 2026-10-23 with pytest 9.1.1 and Python 3.13.5 on Linux. The test file was run verbatim and the output pasted unedited (filtered by the grep shown). PlainHeaders is our extension; Python and pytest are free.