We use fixture finalization to clean up after a test finishes. It helps keep tests independent and tidy by removing temporary data or closing resources.
Fixture finalization (request.addfinalizer) in PyTest
def fixture_name(request): # setup code here def cleanup(): # cleanup code here request.addfinalizer(cleanup) return resource
The request parameter is a special pytest object that gives access to test context.
addfinalizer registers a function to run after the test using this fixture finishes.
import pytest @pytest.fixture def temp_file(request): filename = "temp.txt" with open(filename, "w") as f: f.write("hello") def cleanup(): import os os.remove(filename) request.addfinalizer(cleanup) return filename
addfinalizer.import pytest @pytest.fixture def resource(request): res = acquire_resource() def cleanup(): res.release() request.addfinalizer(cleanup) return res
This test uses a fixture that creates a list. After the test, the list is cleared by the finalizer. The print statements show the order of setup, test, and cleanup.
import pytest @pytest.fixture def sample_list(request): data = [1, 2, 3] print("Setup: Created list") def cleanup(): data.clear() print("Cleanup: Cleared list") request.addfinalizer(cleanup) return data def test_modify_list(sample_list): sample_list.append(4) assert sample_list == [1, 2, 3, 4] print("Test: List modified")
Finalizers run even if the test fails, ensuring cleanup always happens.
You can add multiple finalizers if you need to clean up several things.
Using yield in fixtures is an alternative to addfinalizer for cleanup.
Fixture finalization cleans up resources after tests to keep tests independent.
request.addfinalizer registers cleanup functions to run after tests.
Finalizers run no matter if tests pass or fail, ensuring proper cleanup.