CohortX
Блог

First tests in Python: a practical introduction

2 августа 2026 г. · 2 мин чтения · Читать по-русски · Антон Молотило

Installation and structure

pip install pytest

Tests go in a separate folder alongside the code:

myproject/
  app/
    utils.py
  tests/
    test_utils.py

The naming rule: files start with "test_", and so do the functions inside. Otherwise they simply won't be found.

A first test

from app.utils import shorten

def test_returns_text_unchanged_when_short():
    assert shorten("Hello", 10) == "Hello"

Run from the project root:

pytest

Or verbosely, showing each test:

pytest -v

Checking exceptions

Often you need to confirm a function objects to bad data:

import pytest

def test_raises_on_negative_limit():
    with pytest.raises(ValueError):
        shorten("text", -1)

One test, many cases

Instead of five nearly identical tests, one with parameters:

@pytest.mark.parametrize(
    "text,limit,expected",
    [
        ("hello", 10, "hello"),
        ("a long piece", 5, "a lon…"),
        ("", 5, ""),
    ],
)
def test_shorten(text, limit, expected):
    assert shorten(text, limit) == expected

Each row becomes a separate test. When one case fails, you see exactly which.

Preparing data

When a test needs something set up in advance, that goes into a fixture:

@pytest.fixture
def sample_notes():
    return [
        {"id": 1, "title": "First"},
        {"id": 2, "title": "Second"},
    ]

def test_finds_by_id(sample_notes):
    assert find_note(sample_notes, 2)["title"] == "Second"

The fixture runs before each test that asks for it, sparing you from copying setup into every test.

Testing a service

If you have a web service, you can test it without starting a real server — frameworks provide a test client:

def test_notes_endpoint_returns_list(client):
    response = client.get("/notes")
    assert response.status_code == 200
    assert isinstance(response.json(), list)

Check not only the happy path but the error codes: what comes back for a missing record and for invalid data.

Useful flags

pytest tests/test_utils.py     one file only
pytest -k "shorten"            only tests with this word in the name
pytest -x                      stop at the first failure
pytest --lf                    rerun only last time's failures

The last two save a lot of time while fixing things.

When a test fails

Read the whole output. It shows expected against actual — usually the cause is immediately visible.

Don't edit the test to make it pass. First establish who is wrong: the code or the test. Bending a test to fit broken code is the most harmful habit there is.

Isolate it. Run the failing test alone. Passing alone but failing together means the tests influence each other through shared state. That's a separate and common problem.

What makes tests useful

Independence: every test should work by itself and in any order. Tests that depend on execution order eventually start failing at random, and then nobody trusts them.

Хватит читать — пора делать

На CohortX можно найти команду под пет-проект и получить тот самый опыт, о котором спрашивают на собеседовании.

Похожие статьи