Labs ICT
โญ Pro Login

Yield Fixtures & Cleanup

Using yield to perform teardown logic in fixtures.

Yield Fixtures for Cleanup

Fixtures that use yield instead of return can perform cleanup after the test finishes. Code after the yield statement runs as teardown.

Basic Yield Fixture

import pytest
import tempfile
import os

@pytest.fixture
def temp_file():
    # Setup: create a temporary file
    fd, path = tempfile.mkstemp()
    yield path  # Give the path to the test

    # Teardown: clean up after the test
    os.close(fd)
    os.unlink(path)

def test_write_to_file(temp_file):
    with open(temp_file, "w") as f:
        f.write("hello")
    with open(temp_file) as f:
        assert f.read() == "hello"

# The temp file is automatically deleted after the test

Database Connection Cleanup

A common pattern is setting up and tearing down database connections:

@pytest.fixture
def db():
    connection = create_db_connection()
    connection.begin_transaction()
    yield connection

    # This runs even if the test fails
    connection.rollback()
    connection.close()

def test_insert_user(db):
    db.execute("INSERT INTO users (name) VALUES ('Alice')")
    result = db.execute("SELECT * FROM users")
    assert len(result) == 1

# Transaction is rolled back, database stays clean

Yield with Exception Handling

Teardown code runs even if the test raises an exception:

@pytest.fixture
def resource():
    res = acquire_resource()
    try:
        yield res
    finally:
        # This ALWAYS runs
        res.release()

def test_with_resource(resource):
    assert resource.is_ready()
    # If this test crashes, resource.release() still runs

๐Ÿงช Quick Quiz

What keyword is used in a fixture to perform cleanup/teardown?