Python Academy · Lesson

Fixtures and Setup/Teardown

Use fixtures for shared test state and resource setup.

Lesson 2 of 413 steps

Fixtures and Setup/Teardown is a free Python Academy lesson on CoddyKit. This is lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Python Academy learning path, and your progress syncs across the web and the CoddyKit app. The Python Academy course includes 4 lessons in total.

What Are Fixtures?

Fixtures are functions decorated with @pytest.fixture that provide test dependencies. pytest injects them by name.

import pytest

@pytest.fixture
def user():
    return {"name": "Alice", "age": 30}

def test_name(user):
    assert user["name"] == "Alice"

Setup and Teardown with yield

Yield the fixture value inside a fixture to separate setup (before yield) from teardown (after yield).

import pytest

@pytest.fixture
def db_connection():
    conn = create_connection()  # setup
    yield conn
    conn.close()                # teardown

def test_query(db_connection):
    result = db_connection.query("SELECT 1")
    assert result is not None

Fixture Scopes

Control how often a fixture is created with scope: function (default), class, module, session.

import pytest

@pytest.fixture(scope="module")
def expensive_resource():
    print("\nSetup once per module")
    yield object()
    print("\nTeardown once per module")

Sharing Fixtures via conftest.py

Put fixtures in conftest.py to share them across test files without imports.

# conftest.py
import pytest

@pytest.fixture
def config():
    return {"env": "test", "debug": True}

# test_app.py
def test_env(config):
    assert config["env"] == "test"

Fixture Dependencies

Fixtures can depend on other fixtures by listing them as parameters.

import pytest

@pytest.fixture
def base_url():
    return "http://localhost:8000"

@pytest.fixture
def api_client(base_url):
    return Client(base_url)

def test_get(api_client):
    resp = api_client.get("/health")
    assert resp.status_code == 200

autouse Fixtures

Set autouse=True to apply a fixture to all tests in scope without listing it as a parameter.

import pytest

@pytest.fixture(autouse=True)
def reset_env(monkeypatch):
    monkeypatch.setenv("ENVIRONMENT", "test")

def test_env():
    import os
    assert os.environ["ENVIRONMENT"] == "test"

The tmp_path Fixture

pytest provides tmp_path as a built-in fixture giving a fresh temporary directory per test.

def test_write_file(tmp_path):
    f = tmp_path / "hello.txt"
    f.write_text("hello")
    assert f.read_text() == "hello"

The monkeypatch Fixture

monkeypatch lets you temporarily replace attributes, environment variables, or dictionary entries during a test.

def get_env():
    import os
    return os.environ.get("MODE", "prod")

def test_mode(monkeypatch):
    monkeypatch.setenv("MODE", "test")
    assert get_env() == "test"

The capsys Fixture

capsys captures stdout and stderr output during tests.

def greet(name):
    print(f"Hello, {name}!")

def test_greet(capsys):
    greet("Alice")
    out, err = capsys.readouterr()
    assert out == "Hello, Alice!\n"

Fixture Finalizers with request.addfinalizer

An alternative to yield: register cleanup with request.addfinalizer.

import pytest

@pytest.fixture
def resource(request):
    r = acquire_resource()
    request.addfinalizer(r.release)
    return r

Parametrized Fixtures

Use params in a fixture to run all dependent tests once per parameter value.

import pytest

@pytest.fixture(params=["sqlite", "postgres"])
def db(request):
    return create_db(request.param)

def test_insert(db):
    db.insert({"id": 1})
    assert db.count() == 1

Quick Check

Which fixture scope creates the fixture once for the entire test session?

Recap

Fixtures provide reusable setup/teardown via yield. Use scope to control lifetime, conftest.py for sharing, and autouse=True for implicit application.

Free to start

Learn Python with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
76
Lessons
320

Frequently Asked Questions

Is the “Fixtures and Setup/Teardown” lesson free?

Yes — the full text of “Fixtures and Setup/Teardown” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Python Academy course, upgrade to CoddyKit PRO. The Python Academy course includes 4 lessons in total.

What will I learn in “Fixtures and Setup/Teardown”?

Use fixtures for shared test state and resource setup. You practise Python Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Python Academy?

No prior experience is required. Python Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 4.

How long does the “Fixtures and Setup/Teardown” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Python Academy lesson?

Yes. Every Python Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Writing Your First pytest Tests
  2. Fixtures and Setup/Teardown
  3. Parametrize and Test Coverage
  4. Mocking with unittest.mock
← Back to Python Academy