Python · The language, not just syntax
How do you write maintainable tests with pytest?
Short answer
Structure tests around behaviour, use fixtures for setup and teardown, parametrize inputs, and keep shared configuration in conftest.py. Assertions are plain assert statements with rich failure output.
pytest discovers functions named test_ and runs them with fixtures injected by name. Fixtures can be scoped to a function, module or session, which keeps expensive setup shared without leaking state between tests. Plain assert statements are rewritten to show the compared values on failure.
import pytest
@pytest.fixture
def account():
return Account(owner="Asha", balance=100)
@pytest.mark.parametrize(
"amount,expected",
[(50, 50), (100, 0), (150, -50)],
)
def test_withdraw(account, amount, expected):
account.withdraw(amount)
assert account.balance == expected
def test_rejects_negative(account):
with pytest.raises(ValueError):
account.withdraw(-1)Practices that scale
- Test observable behaviour, not private implementation details
- Use tmp_path for filesystem tests and monkeypatch for environment or attributes
- Mark slow or integration tests so the fast suite stays quick in CI
- Use coverage to find untested branches, not as a target to game
Fixtures should be explicit about their scope. A session-scoped fixture that mutates shared state will create order-dependent failures. Keep tests independent so they can run in any order and in parallel.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What is the purpose of conftest.py?
- 2When would you use a session-scoped fixture?
- 3How do you test that an exception is raised?
- 4Why are order-dependent tests a problem?
Say it in the interview
I write pytest tests around observable behaviour, use fixtures for setup and teardown, and parametrize cases instead of duplicating test bodies. Shared configuration goes in conftest.py, and I keep fixtures at the narrowest scope that still saves time. I mark slow integration tests separately and use coverage to find gaps, not to hit an arbitrary number. Tests must be independent so they can run in any order.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Python mock interview and get scored feedback on depth, clarity and confidence.