Почему написание E2E-тестов — головная боль?
End-to-end тесты считаются золотым стандартом проверки UI, но их поддержка выматывает команды. Типичная картина: тест падает, хотя функциональность работает. Причина — хрупкие локаторы вида div.container > ul > li:nth-child(3) > a. Любое изменение вёрстки ломает десятки тестов. Мы в своей практике сталкивались с проектами, где 35% E2E-тестов были flaky — падали в 15–40% прогонов. Каждый такой ложный сбой отнимает время на разбор, подрывает доверие к автоматизации и замедляет релизный цикл.
Наш AI-генератор решает эту проблему: он создаёт Playwright-тесты с семантическими локаторами (aria-label, data-testid, role), которые устойчивы к косметическим изменениям. Кроме того, нейросеть умеет исправлять уже существующие flaky тесты — анализирует ошибки и добавляет правильные ожидания.
Что такое flaky тесты и почему они возникают?
Flaky тест — это тест, который может упасть без изменений в коде. Основные причины: race conditions (отсутствие ожидания загрузки асинхронных данных), анимации, зависимость от времени или порядка выполнения. По данным Google Flaky Tests at Google and How We Address Them, в крупных проектах до 16% тестов flaky. Мы видели проекты, где этот показатель доходил до 40%.
Как AI-генератор решает проблему flaky тестов?
Наш подход базируется на больших языковых моделях (GPT-4o, Claude 3.5) и включает несколько методов генерации и стабилизации.
Генерация Playwright тестов из описания сценария
Пользователь описывает сценарий на русском или английском языке, указывает URL и тестовые данные. AI преобразует это в TypeScript-код с семантическими локаторами. Пример работы:
from langchain_openai import ChatOpenAI
from playwright.sync_api import sync_playwright
import json
class E2ETestGenerator:
PLAYWRIGHT_PROMPT = """Создай Playwright E2E тест на TypeScript.
Сценарий: {scenario}
URL приложения: {base_url}
Данные для теста: {test_data}
Требования к тесту:
1. Используй semantic locators: getByRole, getByLabel, getByText, getByTestId
2. НЕ используй CSS-селекторы вида .class или #id (кроме data-testid)
3. Добавь явные ожидания: await expect(locator).toBeVisible()
4. Для форм: заполняй через getByLabel(), а не через selectors
5. Проверяй после каждого значимого действия (не только в конце)
6. Используй page.waitForResponse() для ajax-операций
7. Структура: test.describe > test.beforeEach > test
Пример хорошего локатора:
✅ page.getByRole('button', {{ name: 'Создать заказ' }})
✅ page.getByTestId('checkout-submit-btn')
❌ page.locator('button.btn-primary:nth-child(2)')
Верни TypeScript код теста."""
def __init__(self):
self.llm = ChatOpenAI(model="gpt-4o", temperature=0.1)
def generate_from_scenario(
self,
scenario: str,
base_url: str,
test_data: dict
) -> str:
result = self.llm.invoke(
self.PLAYWRIGHT_PROMPT.format(
scenario=scenario,
base_url=base_url,
test_data=json.dumps(test_data, ensure_ascii=False)
)
)
return result.content
def generate_from_recording(self, playwright_trace: str) -> str:
"""Улучшает автоматически записанный тест Playwright Codegen"""
prompt = f"""Улучши автоматически записанный Playwright тест.
Оригинальный тест (из Codegen):
```typescript
{playwright_trace}
Проблемы Codegen-тестов которые нужно исправить:
- Замени хрупкие CSS-селекторы на semantic locators
- Добавь явные ожидания вместо неявных
- Вынеси тестовые данные в переменные
- Добавь проверки состояния (expect) после ключевых действий
- Разбей на логические шаги с комментариями
Верни улучшенный тест.""" return self.llm.invoke(prompt).content
### Screenshot-to-Test: генерация по скриншоту
Если есть UI, но нет документации — AI анализирует скриншот и создаёт тест. Это полезно при реверс-инжиниринге унаследованных систем.
<details>
<summary>Пример генерации из скриншота</summary>
Мы используем GPT-4o для анализа изображения. Модель распознаёт элементы UI и генерирует тест с точностью до 95%.
</details>
```python
import base64
from openai import OpenAI
client = OpenAI()
def generate_test_from_screenshot(image_path: str, scenario: str) -> str:
with open(image_path, "rb") as f:
image_b64 = base64.b64encode(f.read()).decode()
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{image_b64}"}},
{"type": "text",
"text": f"""Создай Playwright тест для этого UI.
Сценарий: {scenario}
Опиши что видишь на скриншоте: форму, кнопки, поля.
Затем создай TypeScript Playwright тест с semantic locators.
Используй getByRole, getByLabel, getByText — не CSS-классы."""}
]
}]
)
return response.choices[0].message.content
Автоматическая генерация Page Object Model
Тесты, сгенерированные «на лету», удобны, но для масштабных проектов нужна структура. AI сам предлагает Page Object — разбивает страницу на логические блоки и создаёт класс с методами.
PAGE_OBJECT_PROMPT = """Создай Page Object Model (POM) класс для страницы.
Описание страницы / скриншот:
{page_description}
URL: {url}
Требования к POM:
- Все интерактивные элементы как свойства класса
- Методы для основных действий (не геттеры для каждой кнопки)
- Методы возвращают Promise<void> или Promise<ResultType>
- Используй semantic locators
- Добавь waitForLoad() метод
Структура:
```typescript
export class CheckoutPage {{
readonly page: Page;
readonly submitButton: Locator;
// ...
async fillOrderForm(data: OrderData): Promise<void> {{
// ...
}}
async submit(): Promise<OrderConfirmationPage> {{
// ...
}}
}}
Верни TypeScript код POM."""
def generate_page_object(self, page_description: str, url: str) -> str:
result = self.llm.invoke(
self.PAGE_OBJECT_PROMPT.format(
page_description=page_description,
url=url
)
)
return result.content
### Исправление flaky тестов
Отдельный модуль анализирует логи падений и автоматически добавляет ожидания, заменяет нестабильные локаторы, фиксит race conditions.
```python
class FlakyTestFixer:
FLAKY_FIX_PROMPT = """Исправь нестабильный (flaky) Playwright тест.
Тест:
{test_code}
Ошибка при последних 5 запусках:
{error_log}
Типичные причины flakiness:
1. Race condition: нет ожидания после async-действия
2. Анимации: элемент видим но кликабелен не сразу
3. Сетевые запросы: нет waitForResponse
4. Дата/время: тест зависит от текущего времени
5. Порядок тестов: глобальное состояние
Добавь:
- await page.waitForLoadState('networkidle') после навигации
- await expect(element).toBeEnabled() перед кликом
- page.waitForResponse() для ajax
- Фиксированное тестовое время через page.clock.setFixedTime()
Верни исправленный тест."""
def fix_flaky_test(self, test_code: str, error_log: str) -> str:
return self.llm.invoke(
self.FLAKY_FIX_PROMPT.format(test_code=test_code, error_log=error_log)
).content
Как мы внедряем AI-генерацию тестов?
Процесс разбит на этапы, каждый завершается измеримым результатом.
| Этап | Длительность | Что получает заказчик |
|---|---|---|
| Анализ UI и сценариев | 2–5 дней | Карта экранов, список критических сценариев, тестовые данные |
| Генерация базовых тестов | 5–10 дней | Playwright-тесты с semantic locators, готовые к запуску |
| Внедрение Page Object Model | 3–5 дней | Структурированный код, переиспользуемые методы |
| Стабилизация существующих тестов | 3–7 дней | Анализ логов, исправление flaky тестов, снижение flaky rate до <5% |
| Интеграция в CI/CD | 2–3 дня | GitHub Actions / GitLab CI, параллельный запуск, Allure-отчёты |
Средний срок по проекту с 10 критическими сценариями: 4–6 недель под ключ.
Что входит в результат?
| Документ/артефакт | Описание |
|---|---|
| Тестовые сценарии | Описание шагов и данных в markdown |
| Исходный код тестов | TypeScript, Playwright, semantic locators |
| Page Object Model | Классы для каждой страницы |
| Отчёты о стабильности | Allure Dashboard с историей прогонов |
| Инструкция по запуску | README с командами и зависимостями |
| Обучение команды | 2 часа воркшопа по поддержке тестов |
Мы даём гарантию: flaky rate не превысит 5% после внедрения. При превышении — бесплатно дорабатываем.
Результаты: сравнение до и после AI
| Метрика | Без AI | С AI |
|---|---|---|
| Flaky rate | 35% | 4% |
| Среднее время прогона одного теста | 15 мин | 11.7 мин |
| Время на написание одного теста | ~4 часа | ~20 минут |
| Доля покрытия критических сценариев | 40% | 95% |
Экономия бюджета QA — до 50% в месяц.
Почему стоит доверить эту задачу нам?
Наша команда имеет 10+ лет опыта в автоматизации тестирования и 4+ года в AI/ML. Мы внедряли E2E-генерацию в финтех, e-commerce и SaaS — всего более 30 проектов. Все инженеры сертифицированы по Playwright и имеют опыт работы с LLM. Мы гарантируем стабильность результатов и прозрачность: вы видите каждый сгенерированный тест и можете его корректировать.
Как начать?
Закажите пилот: мы проанализируем 3–5 ваших сценариев, сгенерируем тесты и покажем результаты. Оценка сроков и стоимости — в течение 24 часов после знакомства с проектом. Получите консультацию — напишите на почту или через форму на сайте.







