Skip to content

Pytest Fixtures

This guide covers pytest fixtures, their usage, and best practices for test setup and teardown.

Table of Contents

Introduction

What are Fixtures?

Fixtures are functions that provide test data or test resources. They can be used to set up preconditions for tests and clean up after tests.

Key Concepts

  • Test setup and teardown
  • Resource management
  • Test isolation
  • Reusable test components

Basic Fixtures

Simple Fixture

1
2
3
4
5
6
7
8
import pytest

@pytest.fixture
def sample_data():
    return {"key": "value"}

def test_with_fixture(sample_data):
    assert sample_data["key"] == "value"

Class Instance Fixture

import pytest

class Calculator:
    def add(self, x, y):
        return x + y

    def subtract(self, x, y):
        return x - y

@pytest.fixture
def calculator():
    return Calculator()

def test_addition(calculator):
    assert calculator.add(2, 3) == 5

def test_subtraction(calculator):
    assert calculator.subtract(5, 3) == 2

Fixture Scope

Function Scope (Default)

1
2
3
4
5
@pytest.fixture
def function_scope_fixture():
    print("Setup")
    yield
    print("Teardown")

Class Scope

1
2
3
4
5
@pytest.fixture(scope="class")
def class_scope_fixture():
    print("Class setup")
    yield
    print("Class teardown")

Module Scope

1
2
3
4
5
@pytest.fixture(scope="module")
def module_scope_fixture():
    print("Module setup")
    yield
    print("Module teardown")

Session Scope

1
2
3
4
5
@pytest.fixture(scope="session")
def session_scope_fixture():
    print("Session setup")
    yield
    print("Session teardown")

Fixture Dependencies

Basic Dependencies

1
2
3
4
5
6
7
@pytest.fixture
def database():
    return Database()

@pytest.fixture
def user(database):
    return database.create_user()

Multiple Dependencies

@pytest.fixture
def config():
    return {"host": "localhost", "port": 5432}

@pytest.fixture
def database(config):
    return Database(config)

@pytest.fixture
def user(database, config):
    return database.create_user(config)

Built-in Fixtures

Temporary Directory

1
2
3
4
def test_file_operations(tmp_path):
    file_path = tmp_path / "test.txt"
    file_path.write_text("Hello, World!")
    assert file_path.read_text() == "Hello, World!"

Temporary File

1
2
3
4
5
def test_file_operations(tmp_path):
    with tempfile.NamedTemporaryFile(dir=tmp_path) as f:
        f.write(b"Hello, World!")
        f.flush()
        assert f.read() == b"Hello, World!"

Monkeypatch

1
2
3
4
5
def test_monkeypatch(monkeypatch):
    def mock_time():
        return 1234567890
    monkeypatch.setattr(time, "time", mock_time)
    assert time.time() == 1234567890

Best Practices

  1. Fixture Organization
  2. Keep fixtures focused and single-purpose
  3. Use clear and descriptive names
  4. Document fixture behavior

  5. Resource Management

  6. Use appropriate scopes
  7. Clean up resources properly
  8. Handle exceptions in fixtures

  9. Test Isolation

  10. Avoid shared state
  11. Use appropriate scopes
  12. Clean up after tests

  13. Performance

  14. Use appropriate scopes
  15. Avoid unnecessary setup
  16. Reuse fixtures when possible

  17. Testing

  18. Debugging
  19. Error Handling
  20. Performance Optimization