tezvyn:

pytest Fixtures: Reusable Test Setups

AI-drafted, machine-checkedSource: docs.pytest.orgbeginner

Pytest fixtures are reusable functions for test setup, like creating sample data. Your tests request them by name as arguments, and pytest automatically runs them and injects the results.

WHY IT EXISTS Many tests require the same initial state, like a database connection or a set of sample data. Writing this setup code in every test is repetitive and error-prone. Fixtures solve this by centralizing setup logic into reusable components, following the Don't Repeat Yourself (DRY) principle.

THE MENTAL MODEL Think of fixtures as a form of dependency injection for your tests. A test function declares what it needs by listing fixture names as its arguments. Pytest acts as the injector, finding and running the corresponding fixture functions and passing their return values into the test. Your test just asks for what it needs, and pytest provides it.

HOW IT WORKS You create a fixture by defining a Python function and decorating it with @pytest.fixture. The function's name is the fixture's identifier. When a test function includes a parameter with that same name, pytest automatically executes the fixture before running the test. The value returned by the fixture function is then passed as the argument to the test function. You never call the fixture function directly.

WHEN TO USE IT Use fixtures for any setup logic shared across multiple tests. This is ideal for creating database connections, initializing complex objects, providing consistent test data, or setting up temporary files. A powerful feature is that fixtures can request other fixtures, allowing you to compose complex test environments from smaller, manageable pieces.

WHEN NOT TO USE IT For setup logic that is truly unique to a single test and will never be reused, it can be simpler to keep the setup code directly inside the test function as part of the "Arrange" step. Creating a fixture for a simple, one-off setup can be unnecessary overhead.

ONE CANONICAL EXAMPLE Imagine testing a function that processes a bowl of fruit. First, you define a fixture to prepare the data: @pytest.fixture def fruit_bowl(): return [Fruit("apple"), Fruit("banana")]. Then, your test requests this data by name: def test_fruit_salad(fruit_bowl):. Before the test runs, pytest executes fruit_bowl() and passes the returned list of fruits into the fruit_bowl argument of your test. The test can then use this pre-arranged data to perform its actions and assertions.

Read the original → docs.pytest.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.