What pytest concepts do you use (fixture, parametrize, scope)?
Answer
Fixtures
- Fixtures provide test dependencies: DB connections, API clients, sample data, mocks. Define with
@pytest.fixture; pytest injects them into test functions by name. Use them to avoid repeating setup/teardown and to share resources across tests. - Example:
def db(): ... yield session; session.close()— the test receivesdb; teardown runs after the test. Userequest.getfixturevalue("fixture_name")when you need a fixture dynamically.
Parametrize
@pytest.mark.parametrize("arg1,arg2", [(a1, a2), (b1, b2)])runs the same test with different inputs. Each tuple is one case; pytest reports pass/fail per case. Use it for boundary values, multiple inputs, or “same logic, different data” without writing duplicate tests.- Combine with fixtures: parametrize can reference fixture names; pytest builds the cartesian product of parametrized args and fixtures when needed. Use
pytest.param(..., id="custom_id")to get readable test IDs.
Scope
- Fixture scope controls how often the fixture is created:
function(default, per test),class(per test class),module(per file),package(per package),session(per test run). Larger scope = fewer creations, but shared state; use for expensive setup (e.g. DB, server) when tests don’t mutate it. Usescope="session"with care to avoid cross-test pollution. - Example:
@pytest.fixture(scope="module")for a single DB connection shared by all tests in the module; useautouse=Trueif every test in the scope should get it without naming it.
Other useful bits
conftest.py: put shared fixtures here; they’re visible to tests in that directory and below.pytest.raises(SomeError),pytest.warns(): assert exceptions and warnings.pytest.approx(): compare floats without brittle equality.
Interview angle
- “What makes a fixture better than setUp?” - explicit dependency by parameter name, composability (fixtures requesting fixtures), and scoping, so an expensive resource is created once per session while cheap state is per test.
- “Which scope do you choose?” - the widest that’s still safe. A database container at session scope with a per-test transaction rollback gives fast, isolated tests; recreating the container per test makes the suite unusable.
- “How do you test many input combinations?” -
@pytest.mark.parametrize, which produces one reported test per case, so a failure names the exact input. A loop inside one test hides which case failed and stops at the first. - “What’s
conftest.pyfor?” - fixtures shared across a directory without importing. Placement matters: it applies to its directory and below, which is how you scope test infrastructure by area.