Тесты — самый болезненный долг в кодовой базе. Они рутинные, повторяющиеся и всегда откладываются «на потом». Именно поэтому тестирование стало одной из первых задач, где AI-агенты показали реальную пользу: цикл «написал тест → запустил → посмотрел на ошибку → починил код» — это именно тот контур, который агент замыкает сам.
Ниже — три конкретных workflow, которые работают сегодня: TDD-цикл с Claude Code и pytest, генерация e2e-тестов через Playwright MCP, интеграционные тесты на pytest с Codex. Каждый — с промптами, командами и честным разбором того, где ломается.
Три типа тестов — три подхода
Прежде чем погружаться в инструменты — какую задачу решает каждый тип теста:
| Тип теста | Что проверяет | Скорость | Что агент делает хорошо |
|---|---|---|---|
| Unit-тесты (pytest) | Одна функция/метод изолированно | <1 с на файл | Генерирует набор кейсов, граничные условия, моки |
| Integration-тесты (pytest) | Взаимодействие модулей, БД, API | 1–30 с | Поднимает fixtures, мокает внешние сервисы, проверяет data flow |
| E2E-тесты (Playwright) | Полный сценарий в браузере | 5–60 с на сценарий | Проходит форму логина, кликает кнопки, проверяет редиректы |
Агент сильнее всего там, где есть объективный критерий: тест прошёл или нет. Но есть нюансы — и о них ниже.
Workflow 1: TDD с Claude Code и pytest
Test-Driven Development с AI-агентом работает иначе, чем вручную. Вы не пишете ни тест, ни код — вы описываете поведение, а агент разворачивает весь цикл: красный → зелёный → рефакторинг.
Пошаговый workflow
Шаг 1. Подготовка проекта. В корне — CLAUDE.md с командой запуска тестов:
# Тестирование
- Фреймворк: pytest
- Запуск: `pytest -v`
- Конфигурация: conftest.py в корне tests/
- Покрытие: pytest-cov
Этот файл агент читает в начале каждой сессии. Без него Claude каждый раз угадывает, как запускать тесты, — и иногда угадывает неправильно.
Шаг 2. Промпт для TDD-цикла. Формулировка — ключевой момент. Промпт «напиши тесты» слишком размытый. Вот конкретный:
Реализуй parse_config(path: str) -> dict:
- читает JSON-файл по пути
- валидирует обязательные поля: host, port, database
- если поле отсутствует —raises ValueError с описанием
- если port вне диапазона 1-65535 —raises ValueError
Напиши pytest-тесты ПЕРВЫМ ДЕЛОМ (TDD), затем реализуй. Запусти pytest -v и исправь всё до зелёного.
Агент делает следующее:
1. Создаёт tests/test_parse_config.py с тестами на happy path и edge cases
2. Запускает pytest -v — все тесты падают (реализации ещё нет)
3. Создаёт src/config.py с реализацией
4. Запускает pytest -v снова — исправляет до зелёного
5. Рефакторит, если есть дублирование
Шаг 3. Циклическая итерация. Если тестов мало — попросите добавить:
Добавь тесты для parse_config: пустой файл, невалидный JSON, файл не найден,
port = 0, port = 99999, пустой объект {}, все поля есть но лишние тоже есть.
Запусти pytest -v и исправь.
Шаг 4. Отдельная сессия для ревью. Лучшая практика из документации Claude Code: запустите отдельную сессию для проверки — агент, который писал тесты, не объективен к своему коду:
Use a subagent to review the test coverage in tests/test_parse_config.py.
Check: are edge cases covered? Are assertions specific (not just "doesn't throw")?
Is there test isolation (no shared state between tests)?
Report gaps only.
Что получается хорошо
- Тесты следуют поведению, а не реализации — агент формулирует их по описанию
- Edge cases, которые разработчик пропускает (пустой файл, невалидный JSON, boundary values), генерируются автоматически
conftest.pyи fixtures создаются по образцу существующих в проекте
Что ломается
- Фиктивные assertion: агент иногда пишет
assert result is not Noneвместо проверки конкретного значения. Лечится явным требованием в промпте: «assert должен проверять конкретное значение, а не факт существования» - Тесты без изоляции: если модуль зависит от filesystem или сети, агент пишет тест, который зависит от окружения. Нужно явно указывать: «мокай все внешние зависимости»
- Длинные сессии: после 20–30 итераций агент «забывает» ранние контракты и ломает то, что уже работало
Workflow 2: E2E-тесты через Playwright MCP
Playwright MCP — это MCP-сервер от Microsoft, который даёт AI-агенту браузер как инструмент. Агент открывает страницу, читает её структуру через accessibility-дерево, кликает по элементам, заполняет формы и видит результат. Ключевая деталь: модель работает не со скриншотами, а со структурированными данными — это надёжнее и дешевле по токенам.
Подключение Playwright MCP
Одна команда для Claude Code:
claude mcp add playwright npx @playwright/mcp@latest
Для Codex CLI:
codex mcp add playwright npx "@playwright/mcp@latest"
Стандартный JSON-конфиг (для Cursor, VS Code, Windsurf):
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}
После подключения у агента появляются инструменты browser_*: browser_navigate, browser_snapshot, browser_click, browser_type, browser_take_screenshot, browser_verify_text_visible и другие.
Для генерации тестов полезен флаг --caps=testing, который добавляет инструменты browser_generate_locator и browser_verify_* (README microsoft/playwright-mcp).
Пошаговый workflow
Шаг 1. Дайте агенту задачу на исследование:
Открой http://localhost:3000/login и сделай полный accessibility-снимок.
Пройди сценарий: введи email user@test.com, пароль test123, нажми «Войти».
Сделай скриншот после успешного входа.
Агент выполнит browser_navigate, browser_snapshot (увидит роли и имена элементов), browser_type дважды, browser_click и browser_take_screenshot. Весь сценарий пройден — теперь агент знает структуру страницы.
Шаг 2. Попросите сгенерировать тест:
На основе пройденного сценария напиши Playwright-тест tests/auth/login.spec.ts:
- сценарий успешного входа
- сценарий неверного пароля (ожидаемая ошибка на странице)
- сценарий пустых полей (ожидаемая валидация)
Используй page.getByLabel для селекторов. После написания запусти npx playwright test.
Агент сгенерирует .spec.ts файл с реальными селекторами из accessibility-дерева, а не с хрупкими CSS-селекторами.
Шаг 3. Повторный прогон и фиксы. Playwright-тесты часто падают из-за таймингов (кнопка ещё не кликабельна, текст ещё не появился). Агент исправляет waitForSelector, waitForURL и ретрай-логику — опять в цикле.
Альтернатива: Playwright CLI вместо MCP
Microsoft параллельно выпустила Playwright CLI с SKILLs — более компактный способ интеграции. Разница:
| Playwright MCP | Playwright CLI + SKILLS | |
|---|---|---|
| Токены в контексте | ~13 700 (21 инструмент) | Значительно меньше |
| Подходит для | Исследовательская автоматизация, self-healing тесты | Высокопроизводительные агенты с большими кодовыми базами |
| Контекст | Постоянное состояние браузера | Команды без состояния |
По документации Playwright MCP, MCP остаётся актуальным для задач, где нужно «поддерживать непрерывный контекст браузера», — например, long-running autonomous workflows. Для кодинг-агентов, которым нужно балансировать между браузером и кодовой базой, CLI предпочтительнее.
Важный момент про токены
Playwright MCP — 21 инструмент, около 13,7 тыс. токенов только на описания (замер Scott Spence). При окне Claude Sonnet в 200 тыс. токенов это почти 7% контекста до первого сообщения. Eugene Trapeznikov рекомендует не держать Playwright подключённым по умолчанию — подключать только когда нужен браузер, а не в каждой сессии.
Workflow 3: Integration-тесты — pytest + Codex
Интеграционные тесты проверяют, как модули работают вместе: API-эндпоинт → валидация → БД → ответ. Для агента это сложнее unit-тестов — нужно поднять fixtures, замокать внешние сервисы и проверить data flow.
Лучший публичный пример — кейс Simon Willison с alchemy-utils: за вечер Codex и GPT-5.6 Sol Ultra собрали кроссплатформенную библиотеку на SQLAlchemy с 164 прошедшими тестами на трёх движках (PostgreSQL, SQLite, DuckDB). Ключевой элемент — промпт с методологией TDD и pytest:
Create a git repo for this and commit and early and often — use uv init to start
the project — use red/green TDD and pytest, see ~/dev/django-sql-dashboard for
one idea as to how the PostgreSQL tests could work
Агент развернул полный процесс без дополнительных указаний: инициализация проекта, изучение референса через grep, red/green циклы (тест → реализация → pytest → коммит), 18 кейсов CRUD на трёх движках с первого прогона.
Пошаговый workflow для интеграционных тестов
Шаг 1. Настройка окружения в CLAUDE.md:
# Тестирование
- Тесты: pytest
- Fixtures: conftest.py с session-scoped для БД
- БД для тестов: SQLite in-memory (по умолчанию), PostgreSQL (по запросу)
- Запуск: `pytest -v --tb=short`
- Моки: pytest-mock для внешних API
Шаг 2. Промпт для интеграционных тестов:
Напиши integration-тесты для модуля orders:
- tests/test_orders.py
- Фикстура: SQLite in-memory база с таблицей orders (id, user_id, status, total)
- Тесты: создание заказа через create_order(), смена статуса, получение списка
по user_id, обработка несуществующего заказа
- Мокай внешний платёжный API (pytest-mock), проверь что он вызывается
с правильными параметрами
- Запусти pytest -v и исправь до зелёного
Шаг 3. Добавление edge cases:
Добавь в test_orders.py:
- параллельное создание двух заказов (конкурентный доступ)
- заказ с total = 0 и total = отрицательное число
- rollback при ошибке платёжного API
Запусти и исправь.
Шаг 4. Проверка через отдельную сессию:
Проведи code review integration-тестов в tests/test_orders.py.
Проверь: тесты изолированы друг от друга?
Каждый тест проверяет одну конкретную вещь?
Есть ли дублирование fixture'ов, которое стоит вынести в conftest?
Codex vs Claude Code для интеграционных тестов
| Codex (OpenAI) | Claude Code (Anthropic) | |
|---|---|---|
| Модель по умолчанию | GPT-5.6 Sol/Terra/Luna | Claude Sonnet 4.5 / Opus |
| Контекстное окно | 200K (GPT-5.6) | 200K (Sonnet) |
| TDD-цикл | Хорошо: промпт + plan → реализация + тесты | Хорошо: plan-режим + итерации |
| Стоимость | Бесплатный план (ChatGPT), API — от $2.5/1M input | API — от $3/1M input |
| Плюс для тестов | Долгие сессии по плану (alchemy-utils: ~32 сообщения) | Subagent-ревью, hooks для автоматической проверки |
Оба инструмента работают. Разница — в экосистеме: Claude Code offers better integration with hooks and subagents for adversarial review, Codex offers simpler pricing via ChatGPT free tier.
Сравнение: какой инструмент для каких тестов
| Задача | Лучший инструмент | Почему |
|---|---|---|
| Unit-тесты для нового модуля | Claude Code + pytest | Plan-режим, быстрые итерации, subagent-ревью |
| TDD-цикл «красный → зелёный» | Claude Code + pytest | Лучший контроль итераций, /rewind при неудаче |
| E2E-тесты для веб-приложения | Claude Code + Playwright MCP | Браузер как инструмент, accessibility-дерево |
| Integration-тесты (БД + API) | Codex + pytest | Долгие сессии, дешёвый бесплатный план |
| Покрытие legacy-кода тестами | Codex + pytest | Промпт «напиши тесты для всех функций в src/» |
| Visual regression тесты | Playwright MCP + скриншоты | browser_take_screenshot + compare |
Советы, которые экономят время
-
Давайте агенту фикстуры-образцы. Не «напиши тесты для БД», а «вот conftest.py с фикстурой для SQLite in-memory — напиши тесты по аналогии». Агент копирует паттерн точнее, чем изобретает новый.
-
Ограничивайте количество тестов за раз. «Напиши 5 тестов для parse_config» лучше, чем «напиши тесты для parse_config». Пять тестов можно проверить вручную за минуту; пятьдесят — нет.
-
Используйте
pytest -xдля ранних итераций. Флаг останавливает на первом падении. Агент исправляет быстрее, когда видит одну ошибку, а не столбец из тридцати. -
Отдельная сессия для ревью. Один агент пишет код, другой — проверяет. В документации Claude Code это называется Writer/Reviewer pattern: «have one Claude write tests, then another write code to pass them» (best practices).
-
Коммитьте после каждого зелёного. Агент умеет коммитить:
git commit -m "test: add parse_config edge cases". Если агент наломал — откат на конкретный коммит, а не на всю сессию. -
Не включайте Playwright MCP по умолчанию. 13,7 тыс. токенов на описания тулов — это дорого для сессий без браузера. Подключайте ad-hoc, когда задача требует e2e (Trapeznikov).
Где агенты при тестировании не помогают
-
Тесты, требующие бизнес-контекста. Агент не знает, что «статус order должен меняться только с pending на paid, но не обратно» — без явного описания в промпте он напишет тест на любое изменение статуса.
-
Сложная оркестрация окружения. Если тесты требуют docker-compose с тремя сервисами, Kafka и Redis — агент может написать код, но поднять окружение и дебажить зависимости между контейнерами придётся вам.
-
Performance-тесты. Агент может написать load-тест с locust или k6, но интерпретацию результатов (p95 латентность, throughput bottleneck) он сделает только по явной инструкции.
-
Тесты на консистентность данных. Проверка, что после ряда операций данные в БД останутся консистентными — требует понимания бизнес-логики, которое у агента ограничено.
-
Фиктивные assertion — хроническая проблема. Агент уверен в своём коде. Тест
assert result is not Noneвыглядит зелёным, но ничего не проверяет. Всегда проверяйте assertion вручную.
Итог
AI-агент не заменяет инженерное тестирование — он убирает барьер на входе. Unit-тесты, которые месяцами откладывались, появляются за вечер. E2e-сценарии, на написание которых раньше уходил день, генерируются из accessibility-дерева браузера. Интеграционные тесты с моками и фикстурами — не самая приятная работа, но агент её делает.
Начните с одного workflow. Самый быстрый старт — TDD с Claude Code и pytest: создайте CLAUDE.md с командой запуска тестов, напишите промпт с описанием поведения и наблюдайте за циклом. Если результат устроит — добавьте Playwright MCP для e2e.
Другие статьи серии: что такое агентный кодинг, кейс alchemy-utils с Codex, Playwright MCP: веб-автоматизация и парсинг.
Источники
- Best practices for Claude Code (документация Anthropic)
- Common workflows: Work with tests (документация Anthropic)
- microsoft/playwright-mcp — README
- microsoft/playwright-cli (CLI + SKILLS альтернатива MCP)
- Simon Willison: alchemy-utils 0.1a0 — TDD с Codex и GPT-5.6
- Транскрипт сессии Codex: alchemy-utils
- Scott Spence: Optimising MCP Server Context Usage in Claude Code
- Eugene Trapeznikov: MCP Profiles — The Config Layer Between User and Repo Config
