Тестирование превратилось в кошмар. Пора его автоматизировать
Вы написали идеальный тест на Playwright. Он проходит по всем страницам, кликает на кнопки, заполняет формы. Вы смотрите на зеленый статус и думаете: «Работает». А потом приходит тикет от пользователя: «После регистрации в личном кабинете пусто». Вы лезете в базу данных и видите, что запись создалась, но с кривыми данными. Классика.
Отдельно тестировать UI — это полдела. Настоящий end-to-end тест проверяет всю цепочку: от клика в браузере до записи в PostgreSQL. Делать это вручную — ад. Писать хрупкие SQL-запросы в каждом тесте — тоже не выход. Нужен другой подход.
Проблема не в инструментах, а в парадигме. Традиционные автотесты проверяют то, что видят. Настоящая бизнес-логика живет в базе данных, и её нужно верифицировать автоматически, в рамках того же тестового прогона.
Решение: Playwright как руки, AI-агент как мозг, MCP — как нервная система
Представьте связку: Playwright (последняя версия 3.2 на 16.04.2026) управляет браузером. AI-агент (например, на базе Claude 3.7 Sonnet 2026 release) анализирует контекст и принимает решения. А между ними работает MCP (Model Context Protocol) сервер — он дает агенту доступ к базе данных, как к обычному инструменту.
Агент не просто выполняет скрипт. Он понимает, что после нажатия кнопки «Сохранить» в UI, в таблице users должна появиться запись с определенным email. И он сам формирует корректный SQL-запрос, выполняет его через MCP и сравнивает результат с ожидаемым. Если что-то не так — падает с понятным объяснением.
1Ставим Playwright и готовим поле для AI
Не будем изобретать велосипед. Создаем новый проект и ставим свежий Playwright.
npm init playwright@latest -- --typescript=yes --github-workflows=no
cd playwright-ai-project
npm installПочему TypeScript? Потому что AI-модели в 2026 году гораздо лучше генерируют и понимают типизированный код. Это снижает количество ошибок на этапе генерации тестов. В playwright.config.ts сразу выставляем таймауты побольше — агент будет думать.
import { defineConfig } from '@playwright/test';
export default defineConfig({
timeout: 120000, // 2 минуты на тест с учетом работы LLM
expect: { timeout: 30000 },
fullyParallel: true,
});2Поднимаем MCP сервер для доступа к БД
Это самый важный этап. Нам нужно дать агенту «руки» чтобы щупать базу данных. Пишем простой сервер на Node.js (или Python), который будет исполнять роль безопасного прокси.
Создаем файл mcp-db-server.js:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { PostgresDriver } from './postgres-driver.js'; // Ваша абстракция для работы с PostgreSQL
const server = new Server(
{ name: 'playwright-db-server', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
// Объявляем инструмент "query_db" для агента
server.setRequestHandler(
'tools/execute',
async (request) => {
if (request.params.name === 'query_db') {
const { sql, params } = request.params.arguments;
// ВАЖНО: Здесь должна быть строгая валидация SQL!
const result = await dbDriver.executeSafeQuery(sql, params);
return {
content: [{ type: 'text', text: JSON.stringify(result) }],
};
}
}
);
await server.listen(3001);Никогда не позволяйте агенту выполнять произвольный SQL без валидации. Ограничьте его только чтением и простыми INSERT в тестовые таблицы. Иначе один неверный промпт сотрет продакшн-данные. (Да, такое уже было).
3Интегрируем AI-агента в тестовый контур
Теперь берем AI-агента. В 2026 году есть куча вариантов: локальный DeepSeek Coder-V3, облачный GPT-4.5 Turbo, или специализированный Claude 3.7 для кода. Его задача — получать контекст (что произошло в UI) и решать, что проверять в БД.
Создаем класс-обертку AIDBVerifier:
import { MCPClient } from 'mcp-client';
export class AIDBVerifier {
private client: MCPClient;
private llm: AIClient; // Ваш клиент к выбранной LLM API
constructor() {
this.client = new MCPClient('http://localhost:3001');
}
async verifyAfterUIAction(uiContext: string, expectedState: string): Promise {
// Генерируем SQL-запрос на основе контекста
const prompt = `
После действия пользователя: ${uiContext}
Ожидаемое состояние в БД: ${expectedState}
Сгенерируй безопасный SQL SELECT запрос для проверки. Только запрос.
`;
const sqlQuery = await this.llm.generate(prompt);
// Выполняем запрос через MCP сервер
const dbResult = await this.client.executeTool('query_db', { sql: sqlQuery });
// Агент интерпретирует результат
const interpretationPrompt = `
Результат запроса: ${dbResult}
Соответствует ли он ожиданию: ${expectedState}? Ответь YES или NO.
`;
const verdict = await this.llm.generate(interpretationPrompt);
return verdict.includes('YES');
}
} Это упрощенная схема. В реальности, как в архитектуре из 11 агентов, за генерацию запроса и интерпретацию отвечают разные специализированные агенты. Это повышает точность.
4Пишем тест, где UI и БД проверяются вместе
Теперь собираем все вместе. Вот как выглядит тест на регистрацию пользователя.
import { test, expect } from '@playwright/test';
import { AIDBVerifier } from '../ai-verifier';
test('Регистрация нового пользователя создает запись в БД', async ({ page }) => {
const verifier = new AIDBVerifier();
// Шаг 1: Действие в UI через Playwright
await page.goto('/register');
await page.fill('#email', 'test@example.com');
await page.fill('#password', 'Secret123!');
await page.click('button[type="submit"]');
// Ждем UI-подтверждения
await expect(page.locator('.success-message')).toBeVisible();
// Шаг 2: Верификация через AI + MCP
const uiContext = 'Пользователь заполнил форму регистрации и нажал Submit.';
const expectedState = 'В таблице users есть запись с email test@example.com и статусом pending';
const dbCheckPassed = await verifier.verifyAfterUIAction(uiContext, expectedState);
// Шаг 3: Assert
expect(dbCheckPassed).toBe(true);
});Магия в том, что вам не нужно знать точную структуру таблицы. AI-агент, обученный на схеме вашей БД (её можно передать в контекст), сам построит правильный запрос. Если завтра колонка status переименуется в account_status, велик шанс, что агент адаптируется — особенно если он использует современную модель с большим контекстом, типа GPT-4.5 Turbo.
Где всё ломается: нюансы, которые не пишут в туториалах
Теория гладкая. Практика — это постоянная борьба с хрупкостью. Вот что бесит больше всего.
- Скорость и стоимость LLM. Каждый вызов к GPT-4.5 — это деньги и время (1-3 секунды). Для сотни тестов это неприемлемо. Решение: использовать маленькие локальные модели (DeepSeek Coder-V3 32B) для простых запросов, а тяжелую артиллерию оставлять для сложных случаев.
- Детерминизм. LLM по природе недетерминированы. Сегодня агент генерирует
SELECT * FROM users WHERE email='test@example.com', а завтра — какой-нибудь джойн на три таблицы. Это ломает стабильность тестов. Фикс: строгие промпты с примерами (few-shot prompting) и пост-обработка SQL через линтер. - Состояние базы. Тест создал пользователя. Следующий тест пытается создать пользователя с тем же email и падает. Классическая проблема очистки состояния. AI-агент должен уметь не только проверять, но и «убирать за собой». Дайте ему через MCP инструмент для удаления тестовых данных.
FAQ: вопросы, которые вы хотели задать, но боялись
| Вопрос | Короткий ответ | Развернутый комментарий |
|---|---|---|
| Это не слишком сложно для команды из 2 QA? | Нет | Настройка MCP сервера — это работа на день. Дальше вы просто используете готовый AIDBVerifier в тестах. Сложность ниже, чем изучать ручное тестирование с нуля. |
| Какую модель LLM выбрать в 2026? | Claude 3.7 Sonnet для точности | Для задач, связанных с кодом и логикой, Anthropic держит марку. GPT-4.5 Turbo быстрее и дешевле. Gemini 2.5 Pro бесподобен в анализе. Можно запустить ансамбль. |
| А если у нас не PostgreSQL, а MongoDB? | Принцип тот же | MCP сервер будет принимать не SQL, а JSON-запросы. Агент легко переключается между языками запросов, если в промпте уточнить: «Сгенерируй запрос для MongoDB». |
| Как убедить менеджмент? | Цифрами | Один такой сквозной тест заменяет: 1) UI-тест Playwright, 2) Ручной запрос в БД, 3) Сравнение данных глазами. Экономия 15-20 минут на каждом серьезном сценарии. За месяц набегают недели. |
Главный страх — «AI всё сломает». Начните с малого: одного теста, одной таблицы, только чтения. Когда убедитесь, что запросы безопасны и точны, масштабируйтесь. Это не революция за день, это эволюция вашего пайплайна.
И да, если вы всё еще пишете SQL вручную для каждого теста, возможно, пора задуматься о фундаментальном изменении подхода. Инструменты для профессиональной автоматизации тестирования уже давно вышли за рамки Selenium и простых скриптов.
Следующий логичный шаг — заставить этого гибридного агента не только проверять, но и генерировать тестовые сценарии, глядя на макет Figma и схему базы данных. Но это уже тема для отдельного разговора. Пока что начните с верификации. Результат вас удивит.