10 промтов для написания unit-тестов и интеграционных тестов: от pytest до Jest
Введение
Тестирование — это не роскошь, а базовая дисциплина в современной разработке. По данным отчета State of Testing 2025, команды, которые пишут тесты до кода (TDD), сокращают количество багов в production на 40–60%. Однако написание качественных тестов отнимает время, которого вечно не хватает.
Современные языковые модели (LLM) умеют генерировать тесты не хуже джуниора, а иногда — и мидла. Главное — правильно составить промт. В этой подборке — 10 проверенных промтов, которые я использую ежедневно в работе с pytest (Python), Jest (JavaScript) и unittest (Python).
Каждый промт сопровождается реальным примером применения и результатом. Никакой воды — только рабочие конструкции.
1. Базовый unit-тест для функции с моками
Промт:
Напиши unit-тест на pytest для функции
get_user_email(user_id), которая делает запрос к внешнему API. Используйunittest.mockдля мока запроса. Проверь успешный ответ и случай, когда API возвращает 404.
Пример использования:
# Функция, которую тестируем
def get_user_email(user_id):
response = requests.get(f"https://api.example.com/users/{user_id}")
if response.status_code == 404:
return None
return response.json()["email"]
Результат генерации:
import pytest
from unittest.mock import patch
from my_module import get_user_email
@patch("my_module.requests.get")
def test_get_user_email_success(mock_get):
mock_get.return_value.status_code = 200
mock_get.return_value.json.return_value = {"email": "test@example.com"}
assert get_user_email(1) == "test@example.com"
@patch("my_module.requests.get")
def test_get_user_email_not_found(mock_get):
mock_get.return_value.status_code = 404
assert get_user_email(999) is None
2. Интеграционный тест с базой данных
Промт:
Напиши интеграционный тест на pytest для функции
create_order(user_id, items), которая сохраняет заказ в PostgreSQL через SQLAlchemy. Используй фикстуру с транзакцией, которая откатывается после теста. Проверь, что заказ создаётся с правильной суммой.
Пример использования:
# Функция, которую тестируем
def create_order(user_id, items, db_session):
total = sum(item["price"] * item["quantity"] for item in items)
order = Order(user_id=user_id, total=total, status="pending")
db_session.add(order)
db_session.commit()
return order.id
Результат генерации:
import pytest
from my_app import create_order, Order
@pytest.fixture
def db_session():
# Настройка тестовой БД
session = get_test_session()
yield session
session.rollback()
def test_create_order_calculates_total(db_session):
items = [{"price": 100, "quantity": 2}, {"price": 50, "quantity": 1}]
order_id = create_order(1, items, db_session)
order = db_session.query(Order).get(order_id)
assert order.total == 250
assert order.status == "pending"
3. Тест для асинхронного кода (pytest-asyncio)
Промт:
Напиши асинхронный тест на pytest с использованием
pytest-asyncioдля функцииfetch_data(url), которая используетaiohttp. Проверь успешный ответ и таймаут.
Результат генерации:
import pytest
from unittest.mock import AsyncMock
from my_module import fetch_data
@pytest.mark.asyncio
async def test_fetch_data_success():
mock_session = AsyncMock()
mock_response = AsyncMock()
mock_response.status = 200
mock_response.json.return_value = {"key": "value"}
mock_session.get.return_value.__aenter__.return_value = mock_response
result = await fetch_data("http://test.com", mock_session)
assert result == {"key": "value"}
@pytest.mark.asyncio
async def test_fetch_data_timeout():
mock_session = AsyncMock()
mock_session.get.side_effect = TimeoutError("Connection timed out")
with pytest.raises(TimeoutError):
await fetch_data("http://test.com", mock_session)
4. Jest-тест для React-компонента
Промт:
Напиши тест на Jest + React Testing Library для компонента
UserProfile, который принимаетuserIdи отображает имя пользователя, полученное через хукuseFetchUser. Проверь состояния загрузки, успеха и ошибки.
Результат генерации:
import { render, screen, waitFor } from '@testing-library/react';
import UserProfile from './UserProfile';
jest.mock('./hooks/useFetchUser');
const mockUseFetchUser = require('./hooks/useFetchUser').useFetchUser;
test('shows loading state initially', () => {
mockUseFetchUser.mockReturnValue({ user: null, loading: true, error: null });
render(<UserProfile userId={1} />);
expect(screen.getByText(/loading/i)).toBeInTheDocument();
});
test('displays user name on success', async () => {
mockUseFetchUser.mockReturnValue({ user: { name: 'Alice' }, loading: false, error: null });
render(<UserProfile userId={1} />);
await waitFor(() => {
expect(screen.getByText('Alice')).toBeInTheDocument();
});
});
test('shows error message on failure', () => {
mockUseFetchUser.mockReturnValue({ user: null, loading: false, error: 'Network error' });
render(<UserProfile userId={1} />);
expect(screen.getByText(/network error/i)).toBeInTheDocument();
});
5. Тест для исключений и краевых случаев
Промт:
Напиши тесты на pytest для функции
divide(a, b), которая выбрасываетValueErrorпри делении на ноль иTypeErrorпри нечисловых аргументах. Используйpytest.raises.
Результат генерации:
import pytest
from my_module import divide
def test_divide_normal():
assert divide(10, 2) == 5.0
def test_divide_by_zero():
with pytest.raises(ValueError, match="Cannot divide by zero"):
divide(10, 0)
def test_divide_non_numeric():
with pytest.raises(TypeError):
divide("10", 2)
6. Параметризованные тесты (pytest.mark.parametrize)
Промт:
Перепиши тесты для функции
calculate_discount(price, discount_percent)с использованием@pytest.mark.parametrize, чтобы покрыть граничные значения: 0%, 50%, 100% и отрицательные значения.
Результат генерации:
import pytest
from my_module import calculate_discount
@pytest.mark.parametrize("price, discount, expected", [
(100, 0, 100),
(200, 50, 100),
(50, 100, 0),
(100, -10, 110), # отрицательная скидка = наценка
])
def test_calculate_discount(price, discount, expected):
assert calculate_discount(price, discount) == expected
7. Тест для Flask/FastAPI эндпоинта
Промт:
Напиши тест на pytest для FastAPI эндпоинта
POST /api/register, который принимает JSON сusernameиpassword, валидирует данные и возвращает токен. ИспользуйTestClient.
Результат генерации:
from fastapi.testclient import TestClient
from my_app import app
client = TestClient(app)
def test_register_success():
response = client.post("/api/register", json={"username": "testuser", "password": "strongpass123"})
assert response.status_code == 200
assert "token" in response.json()
def test_register_missing_field():
response = client.post("/api/register", json={"username": "testuser"})
assert response.status_code == 422
8. Тест для Celery-задачи
Промт:
Напиши тест для Celery-задачи
send_welcome_email(user_email), которая отправляет email через SMTP. Используйpytest-celeryили мок дляsend_email.
Результат генерации:
from unittest.mock import patch
from my_tasks import send_welcome_email
@patch("my_tasks.send_email")
def test_send_welcome_email(mock_send):
send_welcome_email("test@example.com")
mock_send.assert_called_once_with(
to="test@example.com",
subject="Welcome!",
body="Thank you for registering"
)
9. Тест для API с авторизацией (pytest + requests-mock)
Промт:
Напиши тест для функции
get_orders(auth_token), которая делает GET-запрос к защищённому API. Используйrequests-mockдля симуляции ответа. Проверь успешный ответ и 401 Unauthorized.
Результат генерации:
import requests_mock
from my_module import get_orders
def test_get_orders_success():
with requests_mock.Mocker() as m:
m.get("https://api.example.com/orders", json=[{"id": 1}], status_code=200)
result = get_orders("valid_token")
assert result == [{"id": 1}]
def test_get_orders_unauthorized():
with requests_mock.Mocker() as m:
m.get("https://api.example.com/orders", status_code=401)
result = get_orders("invalid_token")
assert result is None
10. Генерация тестовой документации и покрытия
Промт:
Напиши скрипт на Python, который анализирует существующие тесты в папке
tests/и генерирует Markdown-отчёт с покрытием функций. Используйastдля парсинга исходного кода.
Результат генерации:
import ast
import os
def generate_coverage_report(test_dir="tests"):
report_lines = ["# Coverage Report\n", "
| Function | Tested |\n", "|---|---|\n"]
for file in os.listdir(test_dir):
if file.endswith("_test.py"):
with open(os.path.join(test_dir, file)) as f:
tree = ast.parse(f.read())
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
report_lines.append(f"
| {node.name} | ✅ |\n")
return "".join(report_lines)
Заключение
Промты — это не магия, а инструмент, который сокращает рутину. Вместо того чтобы писать 100 строк тестового кода вручную, вы тратите 30 секунд на формулировку запроса и получаете 80% готового решения. Остаётся только проверить и адаптировать под свой проект.
Главное правило: чем конкретнее промт, тем качественнее результат. Указывайте фреймворк, библиотеки для моков, ожидаемое поведение и краевые случаи. Тогда AI сгенерирует тесты, которые можно сразу запускать.
Попробуйте эти промты в своём проекте уже сегодня — и вы заметите, как скорость написания тестов вырастет в 2–3 раза. А если хотите углубиться в тестирование и автоматизацию, обратите внимание на практические курсы, где разбираются реальные кейсы из продакшена.
Комментарии