Генерация тестов с помощью ИИ
Перейти к разделу
Анатомия хорошего AI-сгенерированного теста
ИИ может генерировать тесты быстро, но не все AI-сгенерированные тесты хороши. Хороший тест имеет чёткую цель, тестирует одну вещь, понятное название и поддаётся сопровождению. В этом уроке вы изучите шаблоны промптов, которые приводят к тестам высокого качества.
Самая распространённая ошибка при генерации тестов с ИИ: позволить ИИ генерировать тесты без контекста. Тогда ИИ пишет тесты, проверяющие реализацию (мокирует всё), а не поведение. Всегда давайте контекст — какова цель функции, а не как она реализована.
Шаблоны промптов для юнит-тестов
Шаблон 1: Промпт, ориентированный на поведение
Вместо «напиши тесты для этой функции» опишите поведение, которое хотите протестировать:
# Bad prompt
"Write tests for the calculate_discount() function"
# Good prompt
"Write tests for calculate_discount(). The function:
- Returns 0% discount for orders under 100 EUR
- Returns 5% discount for orders 100-499 EUR
- Returns 10% discount for orders 500+ EUR
- Returns 15% discount for VIP customers regardless of amount
- Raises ValueError for negative amounts
Test each boundary case and VIP + amount combinations.
Use pytest, no mocks."Шаблон 2: Промпт «тест первым»
Попросите ИИ написать тесты ДО того, как он напишет реализацию. Это TDD с ИИ:
# Prompt: "Write pytest tests for a parse_csv_row() function
# that takes a CSV row as a string and returns a dict.
# Expected behavior:
# - Standard row: 'John,Smith,30' -> {'first': 'John', 'last': 'Smith', 'age': 30}
# - Empty field: 'John,,30' -> {'first': 'John', 'last': '', 'age': 30}
# - Quotes: '"John, Jr.",Smith,30' -> {'first': 'John, Jr.', 'last': 'Smith', 'age': 30}
# - Empty string: raises ValueError
# - Wrong field count: raises ValueError"
# AI generates:
import pytest
from myapp.parsers import parse_csv_row
def test_standard_row():
result = parse_csv_row("John,Smith,30")
assert result == {"first": "John", "last": "Smith", "age": 30}
def test_empty_field():
result = parse_csv_row("John,,30")
assert result == {"first": "John", "last": "", "age": 30}
def test_quoted_field_with_comma():
result = parse_csv_row('"John, Jr.",Smith,30')
assert result == {"first": "John, Jr.", "last": "Smith", "age": 30}
def test_empty_string_raises():
with pytest.raises(ValueError):
parse_csv_row("")
def test_wrong_field_count_raises():
with pytest.raises(ValueError):
parse_csv_row("John,Smith")Шаблон 3: Существующий код + пробел в покрытии
Дайте ИИ существующий код И существующие тесты и попросите заполнить пробелы в покрытии:
"Here is the implementation [paste code] and here are the
existing tests [paste tests]. The coverage report shows
that lines 45-67 are not covered. Write tests to cover
those lines. Focus on error handling and edge cases."Генерация интеграционных тестов
Интеграционные тесты сложнее юнит-тестов — они тестируют взаимодействие между компонентами. Для ИИ ключевое — предоставить контекст о всех участвующих компонентах:
# Prompt for integration test:
# "Write an integration test for POST /api/payments/create/.
# The endpoint expects JWT authentication, a payload with course_slug,
# creates a Payment in the DB, and returns a redirect URL.
# Use pytest + Django test client. Real DB, no mocks
# except for the external Comgate API (use respx)."
# AI generates:
import pytest
import respx
from httpx import Response
@pytest.mark.django_db
def test_create_payment_success(authenticated_client, course):
with respx.mock:
respx.post("https://payments.comgate.cz/v1.0/create").mock(
return_value=Response(200, json={
"code": 0,
"transId": "ABC-123",
"redirect": "https://payments.comgate.cz/pay/ABC-123"
})
)
response = authenticated_client.post(
"/api/payments/create/",
data={"course_slug": course.slug},
content_type="application/json",
)
assert response.status_code == 200
data = response.json()
assert "redirect_url" in data
assert Payment.objects.filter(user=authenticated_client.user).exists()Анализ покрытия с помощью ИИ
ИИ помогает не только писать тесты, но и анализировать покрытие, предлагая, где добавить тесты:
# 1. Generate coverage report
pytest --cov=myapp --cov-report=json
# 2. Let AI analyze coverage gaps
claude "Analyze the coverage report in coverage.json.
Identify the 5 most important uncovered areas
and write tests for them. Prioritize by:
1. Business-critical functions
2. Error handling paths
3. Edge cases in data validation"Ревью AI-сгенерированных тестов
Каждый AI-сгенерированный тест необходимо проверять. Ищите следующие проблемы:
- Тавтологичные тесты — тест, проверяющий, делает ли реализация то, что делает (assert result == function(input))
- Избыточное мокирование — тест, мокирующий всё и не тестирующий ничего реального
- Отсутствие assertions — тест, который всегда проходит, потому что у него нет assert в нужном месте
- Захардкоженные значения — тест, проходящий только для конкретных данных и ломающийся при изменениях
- Отсутствие очистки — тест, оставляющий состояние (файлы, записи в БД), влияющее на другие тесты
Практическое правило: если вы не можете понять, что тестирует тест, в течение 5 секунд после его чтения — тест плохой. ИИ часто пишет тесты с неясными именами. Переименуйте тест, чтобы описать ожидаемое поведение, а не детали реализации.
Выберите один модуль в вашем проекте с недостаточным покрытием тестами: 1. Запустите отчёт о покрытии и определите непокрытые строки 2. Используйте ИИ (Claude Code, Copilot или Cursor) для генерации тестов 3. Используйте все три шаблона промптов: ориентированный на поведение, тест-первым, пробел в покрытии 4. Проверьте каждый сгенерированный тест по чеклисту выше 5. Запустите тесты и убедитесь, что они проходят и увеличивают покрытие Сравните качество тестов из разных шаблонов промптов. Какой шаблон дал лучшие тесты?
Подсказка
Начните с простой утилитарной функции — чистые входные данные, чистые выходные, нет побочных эффектов. Там ИИ показывает себя лучше всего. Затем попробуйте более сложную функцию с обращениями к базе данных или API. Вы увидите, где ИИ начинает нуждаться в большем контексте.
- Промпты, ориентированные на поведение, дают лучшие тесты, чем общие «напиши тесты для X»
- Предоставляйте ИИ контекст об ожидаемом поведении, а не только о реализации
- Всегда проверяйте AI-сгенерированные тесты — ищите тавтологии, избыточные моки и отсутствие assertions
- TDD с ИИ: попросите ИИ написать тесты до реализации
- Анализ пробелов в покрытии: дайте ИИ отчёт о покрытии и пусть он заполнит недостающие тесты
В следующем уроке мы разбираем визуальное регрессионное тестирование — техника, которая даст вам явное преимущество. Разблокируйте полный курс и продолжайте прямо сейчас.
2/7 завершено — продолжайте!