Fixtures

Test fixtures initialize test function and create any preconditions required to run the tests. They are responsible for creating reproducible tests, because they ensure the prerequisites are always the same. Fixtures are reusable and can be used by multiple tests, as opposed to code written in the arrange step of a test function.

Fixtures also allow for cleaning up and tearing down of any resources needed to run the tests. An example is a temporary folder, which is created before the test is run and deleted afterwards, ensuring no old data stays around.

It’s possible to implement a fixture as a simple function. But test frameworks usually offer some advantages for fixtures over using simple functions. We will take a look how pytest implements fixtures.

Fixtures in pytest

In pytest, fixtures are defined simple functions. To define a fixture, simply create a function and use the @pytest.fixture decorator:

@pytest.fixture
def my_asset():
    return Asset(id=1, name='test_asset')

To use a fixture, simply put their name in the argument list of the test function. Pytest will automatically discover the correct function by their name, call the fixture function and pass the result as an argument to the test function.

def test_asset_validation(my_asset):
    is_valid = validate_asset(my_asset)
    
    assert is_valid

Fixtures can also require other fixtures:

@pytest.fixture
def my_project():
    return Asset(id=1, name='test_asset')

@pytest.fixture
def my_asset(my_project):
    return Asset(id=1, name='test_asset', project=my_project)

Some fixtures may require some cleanup after test execution. We can achieve this by using a yielding fixture:

@pytest.fixture
def my_tmp_folder():
	# setup
	temp_dir = tempfile.mkdtemp()

	yield temp_dir
	#teardown
	shutil.rmtree(temp_dir)

Code before the yield statement is executed once the fixture is instantiated. In our example, a temporary folder is created. The value returned by yield is passed to the test function. All code after the yield statement is executed after the text execution. In our example, we need to clean up the temp folder.

Pytest already offers some ready to use fixtures, such as a built-in tmpdir fixture for temporary directories. For more details, see the pytest documentation.


Last modified September 16, 2020