In pytest, a fixture is a function that sets up something your tests need — like a database connection, temporary file, or test configuration — and then optionally tears it down when the test is done.
Marks a fixture to run automatically before (and after) each test, without having to include it as an argument in your test functions.
import os
import pytest
@pytest.fixture(autouse=True)
def change_user_env():
original = os.environ.get("USER")
os.environ["USER"] = "foobar"
yield
os.environ["USER"] = original
def test_user():
assert os.getenv("USER") == "foobar"
Runs before and after every test.
No need to specify the fixture in test function arguments.
Good for lightweight, repeated setup that applies to every test.
Temporary environment variable changes
Automatically logging test execution
Resetting configuration or shared state
Heavy setup/teardown (e.g., starting/stopping a database)
Anything time-consuming that’s not needed by every test
If you have 20 tests and your autouse=True fixture connects to a database, it will open and close the connection 20 times — slow!
Specifies that a fixture should be created once per module (test file) and reused for all tests in that module.
import pytest
@pytest.fixture(scope="module")
def database():
db = connect_to_db()
yield db
db.close()
def test_insert(database):
database.insert("abc")
def test_query(database):
assert database.query("abc") == True
Sets up the fixture once per file (module).
Cleans up after all tests in that file finish.
✅ Keeps resource-heavy fixtures efficient and shared.
Shared database connections
External service clients (e.g., AWS, API clients)
Web or test servers needed across many tests
You can technically use autouse=True and scope="module" together
But only do this when all tests in the module truly depend on that setup. Otherwise, it's better to inject the fixture explicitly to make the dependency clearer.