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
- FAILED: something went wrong inside the test function: a failing
assert, or any other exception raised in the test body (theKeyErrorcounts as a failure too, not an error). - ERROR: something went wrong outside the test function, in a fixture: during setup (the test never ran) or during teardown (after the test already ran). A misspelled fixture name (
fixture 'dbb' not found) is also an error at setup.
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
- Run the single test with
pytest -x path::test_nameand read the traceback under "ERROR at setup": the last frames are inside the fixture. pytest --fixtureslists the fixture names available, which catches typos.- If a setup failure means an external service is down rather than a bug, call
pytest.skip("database not reachable")in the fixture so the test is reported as skipped instead of erroring. - Make teardown code tolerant (e.g.
missing_ok=Truewhen deleting files) so a cleanup problem does not hide a passing test.
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.