pytest Fixtures

Fixtures in pytest are a powerful way to manage setup and teardown tasks, ensuring your test environment is prepared and consistent. They help eliminate repetitive code by providing reusable and flexible components.


What Are Fixtures and Why Use Them?

Fixtures are functions that provide a fixed baseline for your tests. They help:

  • Set up test environments before tests run.
  • Clean up resources after tests complete.
  • Simplify test code by eliminating repetitive setup logic.

Example Use Case

Consider testing a function that interacts with a database. Instead of initializing the database in every test, you can create a fixture to handle this setup.


Defining and Using Fixtures

You define a fixture using the @pytest.fixture decorator and include it as an argument in test functions that need it.

Basic Fixture Example

Fixture Definition:

import pytest
 
@pytest.fixture
def sample_data():
    return [1, 2, 3, 4, 5]

Using the Fixture in Tests:

def test_sum(sample_data):
    assert sum(sample_data) == 15
 
def test_length(sample_data):
    assert len(sample_data) == 5
  • pytest automatically detects the sample_data fixture and passes its return value to the test functions.

Fixture Scope: Function, Module, Class, and Session

Fixture scope determines how often a fixture is created and destroyed.

Scope Levels

  1. Function (default):

    • The fixture is created separately for each test function.

    Example:

    @pytest.fixture(scope="function")
    def resource():
        return "function scoped"
  2. Module:

    • The fixture is created once for all tests in a module.

    Example:

    @pytest.fixture(scope="module")
    def resource():
        return "module scoped"
  3. Class:

    • The fixture is created once for all tests in a class.

    Example:

    @pytest.fixture(scope="class")
    def resource():
        return "class scoped"
  4. Session:

    • The fixture is created once for all tests in a session (entire test suite).

    Example:

    @pytest.fixture(scope="session")
    def resource():
        return "session scoped"

Using Fixtures in Multiple Test Cases

Fixtures can be used across multiple test cases and combined for more complex setups.

Example: Combining Fixtures

Define Fixtures:

@pytest.fixture
def numbers():
    return [1, 2, 3]
 
@pytest.fixture
def multiplier():
    return 2

Use in Tests:

def test_multiplication(numbers, multiplier):
    result = [n * multiplier for n in numbers]
    assert result == [2, 4, 6]
 
def test_sum(numbers):
    assert sum(numbers) == 6

Example: Dependent Fixtures

Fixtures can depend on other fixtures.

@pytest.fixture
def base_value():
    return 10
 
@pytest.fixture
def incremented_value(base_value):
    return base_value + 5
 
def test_increment(incremented_value):
    assert incremented_value == 15

Summary

  • Fixtures simplify repetitive setup and teardown logic in tests.
  • Use the @pytest.fixture decorator to define reusable fixtures.
  • Scope can control how often fixtures are created: per function, module, class, or session.
  • Combine and reuse fixtures for flexible and clean test setups.

pytest fixtures are an essential tool for scalable and maintainable test suites. Start incorporating them to streamline your testing workflow!