Лучшие практики Playwright и 10 ошибок ИИ-агентов

🔥 Важное для QA-специалистов! 🔥
В QaRocks ты найдешь туториалы, задачи и полезные книги, которых нет в открытом доступе. Уже более 18.000 подписчиков – будь среди нас! Заходи к нам в телеграм канал QaRocks

Лучшие практики Playwright — это правила, которые обеспечивают стабильность и читаемость браузерных тестов. Используйте локаторы на основе ролей (поиск по тому, что видят пользователи), утверждения, ориентированные на веб-пространство и автоматически ожидающие завершения, а также изолированные тесты. Заполняйте данные через API (прямые запросы), а не через пользовательский интерфейс. Избегайте жестких ожиданий, условной логики и тестов, привязанных к вашему HTML. Включите трассировку и запускайте тесты параллельно.

Искусственный интеллект может написать 50 Playwright-тестов за минуту. Это кажется очень быстро.

Затем эти тесты случайным образом терпят неудачу, и никто не знает почему. Агент скопировал старые шаблоны из своих обучающих данных. Он не знает, что запуск теста провалился прошлой ночью.

В этом руководстве перечислены 10 лучших практик, обеспечивающих стабильность тестов. Для каждой из них я привожу небольшой правильный пример. Я также показываю, какие ошибки допускают агенты ИИ в коде. Инструменты ИИ, такие как Copilot, Cursor и даже генератор кода Playwright (запись тестов), опираются на устаревшие привычки. Кто-то должен это исправить.

1. Находите элементы так, как их видит пользователь

Идентификатор (указатель на элемент) должен соответствовать тому, что пользователь видит на экране. Используйте методы getByRole, getByLabel или getByText. Они отображают текст так же, как он представлен на странице. Кроме того, они сохраняются даже при переработке HTML-кода.

import { test, expect } from '@playwright/test';
test('user can sign in', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('ada@example.com');
  await page.getByRole('button', { name: 'Sign in' }).click();
});

Ошибка, которую допускают агенты ИИ: они пытаются использовать CSS или XPath (ненадежные селекторы пути), например page.locator('div.btn-primary > span'). Измените одно имя класса, и тест сломается.

2. Используйте веб-ориентированные утверждения (web-first assertions), которые сами ожидают выполнения

Проверка, ориентированная на веб-приложения (проверка с автоматическим ожиданием), повторяет попытку до тех пор, пока страница не будет готова. expect(locator).toBeVisible() ожидает самостоятельно. Вам никогда не придется добавлять фиксированную задержку (sleep).

import { test, expect } from  '@playwright/test' ;
test('welcome message appears', async ({ page }) => {
  await page.goto('/dashboard');
  await expect(page.getByText('Welcome back')).toBeVisible();
});

Что не так у агентов ИИ: они добавляют await page.waitForTimeout(3000) (жесткую паузу). Жесткие паузы — главная причина нестабильных тестов (тестов, которые проваливаются случайным образом). Слишком короткая пауза приводит к провалу теста. Слишком длинная замедляет работу всего набора тестов.

3. Храните каждый тест в изолированном месте

Изолированность означает, что каждый тест начинается с чистого листа. Нет общего входа в систему. Нет остаточных данных от предыдущего теста. Playwright предоставляет каждому тесту новый контекст браузера (чистую сессию). Состояние настраивается в хуке, а не между тестами.

import { test, expect } from  '@playwright/test' ;
test('opens an existing project', async ({ page, request }) => {
  const res = await request.post('/api/projects', {
    data: { name: 'Apollo' },
  });
  expect(res.ok()).toBeTruthy();
  await page.goto('/projects');
  await expect(page.getByText('Apollo')).toBeVisible();
});

Ошибка, которую допускают агенты ИИ: они объединяют тесты в цепочку, где для выполнения второго теста сначала должен быть выполнен первый. Одна ошибка приводит к повреждению всего файла.

4. Задавайте начальное состояние через API, а не через пользовательский интерфейс

Чтобы протестировать страницу, часто сначала нужны данные: пользователь, заказ, черновик. Не нужно прокликивать десять экранов, чтобы их создать. Отправляйте данные напрямую на ваш бэкенд с помощью фикстуры request (встроенного HTTP-клиента). Это быстрее и стабильнее.

import { test, expect } from  '@playwright/test' ;
test('opens an existing project', async ({ page, request }) => {
  const res = await request.post('/api/projects', {
    data: { name: 'Apollo' },
  });
  expect(res.ok()).toBeTruthy();
  await page.goto('/projects');
  await expect(page.getByText('Apollo')).toBeVisible();
});

Ошибка, которую допускают агенты ИИ: они каждый раз формируют данные через пользовательский интерфейс. Тестирование становится долгим и медленным, а этап настройки завершается неудачей по причинам, не имеющим отношения к реальной проверке.

5. Не следует по умолчанию полагаться на идентификаторы тестов

Идентификатор теста (тег, добавленный специально для тестов, например data-testid) служит запасным вариантом. В первую очередь используйте getByRole и getByLabel — они проверяют то, с чем реально взаимодействует пользователь. Тестовый ID же лишь подтверждает наличие атрибута.

import { test, expect } from  '@playwright/test' ;
test('cart shows one item', async ({ page }) => {
  await page.goto('/cart');
  // Prefer a real role over a test id.
  await expect(page.getByRole('listitem')).toHaveCount(1);
});

Что не так у агентов ИИ: они вставляют текст data-testid повсюду. Тесты проходят, даже когда у кнопки нет подписи, и программа чтения с экрана (вспомогательное программное обеспечение) не может её найти. Тест пропускает реальную ошибку.

6. Включите трассировку при первой повторной попытке

Трассировка (полная запись выполнения) показывает каждый шаг, DOM и сеть. Настройте запись только при первой попытке повторного выполнения неудачного теста. Вы получите доказательства сбоев, а чистые запуски будут работать быстрее.

// playwright.config.ts 
import { defineConfig } from  '@playwright/test' ;
export default defineConfig({ 
  retries: 1, 
  use: { 
    trace: 'on-first-retry', 
  }, 
});

Что делают неправильно агенты ИИ: они оставляют трассировку отключенной или устанавливают trace: 'on' для каждого запуска. Отключение означает отсутствие данных о неудачном выполнении теста. Постоянное включение замедляет работу набора тестов и заполняет дисковое пространство.

7. Запускайте тесты параллельно и используйте шардирование (sharding)

Параллельный режим означает одновременное выполнение множества тестов. Playwright делает это по умолчанию. Для одного большого файла с независимыми тестами установите параллельный режим. Чтобы распределить медленный набор тестов по разным машинам, используйте шардирование (запуск своей части на каждой машине).

import { test, expect } from  '@playwright/test' ;
test.describe.configure({ mode: 'parallel' });
test('loads home', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveTitle(/Home/);
});

Разделение на три машины в CI (сервере сборки):

npx playwright test --shard=1/3

Ошибка, которую допускают агенты ИИ: они пишут тесты, которые используют одну и ту же строку базы данных или одного и того же пользователя. Если запускать их параллельно, они будут конфликтовать друг с другом, что приведет к нестабильной работе тестов.

8. Избегайте ветвлений (if) и блоков try в тестах

Тест должен следовать одному четкому сценарию. Никаких ветвлений. Если тест «спрашивает»: «Кнопка на месте? Если да, кликни по ней», — он скрывает баг. Кнопка всегда должна быть на месте. Просто используйте assertion.

import { test, expect } from  '@playwright/test' ;
test('checkout button works', async ({ page }) => {
  await page.goto('/cart');
  // Assert the state. Do not guess it with an if.
  const checkout = page.getByRole('button', { name: 'Checkout' });
  await expect(checkout).toBeEnabled();
  await checkout.click();
});

Ошибка, которую допускают агенты ИИ: они обворачивают клики в if (await locator.isVisible()), чтобы избежать ошибок. Это скрывает реальный сбой. Тест, который пропускает собственную проверку, всё равно остается «зеленым».

9. Тестируйте то, что видят пользователи, а не то, как это построено

Проверяйте поведение, а не внутренние механизмы. Проверяйте видимый результат. Не проверяйте CSS-классы, переменные состояния или имена функций. Они изменяются при рефакторинге (переписывании кода), даже если приложение продолжает работать.

import { test, expect } from  '@playwright/test' ;
test('shows a success message after submit', async ({ page }) => {
  await page.goto('/contact');
  await page.getByLabel('Message').fill('Hello');
  await page.getByRole('button', { name: 'Send' }).click();
  // Check the user-facing result, not an internal class.
  await expect(page.getByText('Thanks, we got your message')).toBeVisible();
});

Ошибка, которую допускают агенты ИИ: они делают проверки на class="is-active" или точную структуру HTML. Тест ломается при каждом редизайне, даже если на самом деле ничего не изменилось.

10. Определяйте проекты в конфигурации

Проект (именованная тестовая среда) playwright.config.ts запускает одни и те же тесты при разных настройках. Используйте проекты для охвата Chromium, Firefox и WebKit (трех основных браузерных движков). Одна конфигурация — полное покрытие.

// playwright.config.ts <br>import { defineConfig, devices } from  '@playwright/test' ;
export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  retries: 1,
  use: { trace: 'on-first-retry' },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit', use: { ...devices['Desktop Safari'] } },
  ],
});

Какие ошибки допускают агенты ИИ: они жестко прописывают один браузер или копируют конфигурационный файл без массива projects. В результате тестовый набор проверяет только Chrome, и баг, проявляющийся исключительно в Safari, попадает к пользователям.

Человек по-прежнему задает стандарт

ИИ быстро создает первый черновик. Это действительно так, и это удобно. Но в первом черновике он копирует шаблоны со старого кода в интернете: добавляет жесткие задержки (hard waits), прокликивает UI для создания данных и обворачивает хрупкие шаги в блоки if, чтобы прогон оставался «зеленым».

«Зеленый» набор тестов, который ничего не доказывает, хуже, чем отсутствие тестов вовсе. Он лишь создает ложное чувство уверенности.

Поэтому рабочий процесс прост: позвольте агенту написать черновик, а затем проверяйте этот черновик на соответствие 10 правилам из этой статьи и исправляйте ошибки ИИ. Агент обеспечивает скорость, а человек сохраняет честность тестов. В этом и заключается работа AI QA Architect.

Создавайте тесты с помощью ИИ, но доводите их до стабильности самостоятельно.

Перевод статьи «Playwright Best Practices: 10 Rules AI Agents Get Wrong (2026)».

🔥 Какой была ваша первая зарплата в QA и как вы искали первую работу? 

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Читать в телеграм

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *