Testing
pytest
Python's main testing framework: plain asserts, fixtures and parametrization.
What it is
pytest is an open source community project started by Holger Krekel. Tests are plain functions with a simple assert, no base classes or special methods. pytest rewrites assert to show a detailed diff on failure.
Its core strength is fixtures (setup and teardown of dependencies injected by argument name), parametrization (@pytest.mark.parametrize) and a plugin ecosystem (pytest-cov, pytest-asyncio, pytest-django, pytest-xdist).
It also runs unittest-style tests. pytest is used to test applications, FastAPI and Django APIs, as well as data and ML code.
Use it when
- Any Python project: libraries, web APIs, scripts.
- You need parametrization and reusable fixtures.
- You want readable failure messages without extra code.
Avoid it when
- A project where the team strictly sticks to
unittestand does not want to change. - Tests are not in Python: use your language's tools.
Key concepts
- Fixture
- A function with
@pytest.fixturethat prepares a resource; a test receives it by argument name. - Parametrize
- One test runs over a set of inputs.
- Markers
- Marks like
skip,xfailand custom ones to select tests. - monkeypatch and tmp_path
- Built-in fixtures for patching and temporary files.
- conftest.py
- A file with shared fixtures for a test directory.
Example
Interview questions
1. What is a fixture and why?
A function that prepares data or a resource for a test and cleans up after it if needed (via
yield). A test just names it in arguments.scopesets the lifetime: function, module, session.2. How do you parametrize a test?
With the
@pytest.mark.parametrize('a, b', [...])decorator. pytest creates a separate test for each value pair with its own result.3. How does pytest differ from unittest?
Plain functions and
assertinstead of classes andassertEqualmethods, powerful fixtures, parametrization and plugins. It also runsunittesttests.4. How do you replace an external dependency?
With the
monkeypatchfixture orunittest.mock.patch. Patch network calls, environment variables and time so the test is isolated.
Interview questions from the bank
- Coverage is 92 %, CI has a 90 % threshold, yet a bug in the discount calculation reached production. The buggy line was executed by a test; the test just did not check anything about the result. What do you propose to the team?JuniorTesting
- An 80 line test creates five objects, calls three functions and has 12
expectcalls. When it fails, nobody can quickly tell what broke. How do you rework it?JuniorTesting - A file has 14 nearly identical tests for a phone number validator, copied from one another. A new rule needs changes in all 14. How do you rework it, and when does that approach do harm?JuniorTesting
- A bug: users in time zones west of UTC, for example in the US, see yesterday's date on their invoice. You found the cause. What exactly do you do with tests before the fix and after it?JuniorTesting
- Repository tests run on in memory SQLite while production runs Postgres. A query with
ON CONFLICT ... DO UPDATEandjsonbpassed the tests and failed in production. How do you set up database tests instead, and how do you keep them fast?MiddleTesting - A pytest suite: each test is green on its own, but run together random tests fail. The
userfixture hasscope='session', and one of the tests changes this user's email. What is happening, and how should the fixtures be split?MiddleTesting - Integration tests run on a shared 2 GB database dump and rely on 'user 42' and 'order 1001'. After a required column was added, 200 tests failed, and nobody knows what data they actually need. What do you move to?MiddleTesting
- The backend team renamed the
pricefield toamountin an API response. Their tests are green, the mobile app's tests are green because the API is mocked there, and in production the app shows empty prices. How do you set up the process so this is caught before release, and where will contract testing not help?SeniorTesting
Related technologies
- PythonA readable general-purpose language: web, data, automation and machine learning.
- FastAPIA modern Python API framework built on type hints, with automatic validation and OpenAPI docs.
- DjangoA batteries-included Python framework: ORM, admin, auth and templates.
- FlaskA Python microframework: a minimal core with routing and templates, the rest through extensions.
Logos belong to their owners and are used for identification only. Icons: Simple Icons (CC0), Devicon (MIT).