Тестирование Playwright

В этой главе рассказывается, как написать и запустить первый тест Playwright, что поможет вам понять основные компоненты и процесс выполнения теста.


Запустите пример теста

После инициализации проекта сначала запустите автоматически созданный пример теста, чтобы убедиться, что всё работает:

# 运行所有测试
npx playwright test

После запуска вы увидите вывод, похожий на следующий:

Running 6 tests using 4 workers

  ✓  1 [chromium] › tests/example.spec.ts:3:1 › has title (2.1s)
  ✓  2 [chromium] › tests/example.spec.ts:10:1 › get started link (1.8s)
  ✓  3 [firefox] › tests/example.spec.ts:3:1 › has title (1.9s)
  ✓  4 [firefox] › tests/example.spec.ts:10:1 › get started link (1.7s)
  ✓  5 [webkit] › tests/example.spec.ts:3:1 › has title (2.3s)
  ✓  6 [webkit] › tests/example.spec.ts:10:1 › get started link (2.0s)

  6 passed (12s)

Из вывода видно: тесты выполнили по 2 теста в каждом из 3 браузеров, всего 6 тестов, все прошли.


Создайте свой первый файл теста

Понятноtests/example.spec.tsсодержимое, и давайте напишем тест с нуля.

Пример

// Путь к файлу: tests/first-test.spec.ts
import { test, expect } from '@playwright/test';

// test(name, callback) определяет тест
// name: имя теста, отображаемое в отчёте о тестах
// Параметр callback { page } — это фикстура, предоставляемая Playwright
test('Посетите главную страницу EXAMPLE и проверьте заголовок', async ({ page }) => {
  // Перейдите по указанному URL
  await page.goto('https://www.example.com/');

  // Утверждение: заголовок страницы содержит "EXAMPLE"
  await expect(page).toHaveTitle(/EXAMPLE/);
});

Запустите этот тест:

npx playwright test tests/first-test.spec.ts

Ожидаемый вывод:

Running 1 test using 1 worker

  ✓  1 [chromium] › tests/first-test.spec.ts:4:1 › 访问 EXAMPLE 首页并检查标题 (2.5s)

  1 passed (2.5s)

Подробное объяснение функции test()

test()Это основная функция Playwright Test, используемая для определения тест-кейса.

Базовый синтаксис

Пример

import { test, expect } from '@playwright/test';

// test(имя теста, функция теста)
test('Описательное имя теста', async ({ page }) => {
  // Операции в тесте
  await page.goto('https://example.com');

  // Утверждения в тесте
  await expect(page).toHaveTitle(/Example/);
});

Описание параметра

ПараметрTypeОписание
Первый параметр (имя теста)stringОписательное имя теста, отображаемое в отчётах о тестах и логах.
Второй параметр (тестовая функция)async (fixtures) => {}Асинхронная функция, содержащая фактическую логику теста.

Что такое фикстура page?

{ page }Это тот, что в параметрах функции тестадеструктурирующее присваиваниеон извлекает из объекта фикстуры, предоставленного Playwrightpage。

pageявляетсяобъектом Pageпредставляющим вкладку браузера.

Каждый тест имеет свой собственный независимыйpageэкземпляр:

фикстураTypeОписание
pageобъект PageНезависимая вкладка браузера, используемая для навигации, действий и утверждений
contextобъект BrowserContextКонтекст браузера, управляет файлами cookie, хранилищем и т. д.
browserобъект BrowserЭкземпляр браузера, редко используется напрямую
requestобъект APIRequestContextИспользуется для отправки HTTP-запросов (не через браузер)

Наиболее часто используетсяpage, подавляющее большинство операций выполняется через него.


навигация page.goto()

page.goto(url)Это одна из самых базовых операций в Playwright, используемая для перехода по указанному URL.

Пример

// Базовое использование
await page.goto('https://www.example.com/');

// Навигация с параметрами
await page.goto('https://www.example.com/', {
  // Ожидать срабатывания события 'load' (значение по умолчанию)
  waitUntil: 'load',
  // Тайм-аут операции (миллисекунды)
  timeout: 30000,
  // Реферер (заголовок Referer)
  referer: 'https://www.google.com/',
});

waitUntilУ этой опции есть три возможных значения:

ЗначениеЗначениеСценарий применения
'load'Ожидать срабатывания события loadЗначение по умолчанию, подходит для большинства страниц
'domcontentloaded'Ожидать наступления события DOMContentLoadedВам нужно только, чтобы загрузилась базовая структура страницы
'networkidle'Дождаться, пока сеть перейдёт в состояние простоя (никаких новых запросов в течение 500ms)Когда нужно дождаться загрузки всех асинхронных данных

В подавляющем большинстве случаев используйте значение по умолчанию'load'и всё. Автоматический механизм ожидания Playwright решит последующие проблемы с доступностью элементов, поэтому нет необходимости использовать'networkidle'。


проверки expect()

expect()Это метод проверки Playwright, используемый для проверки того, соответствуют ли результаты теста ожиданиям.

Пример

// Утверждение заголовка страницы
await expect(page).toHaveTitle(/EXAMPLE/);

// Утверждение URL страницы
await expect(page).toHaveURL('https://www.example.com/');

// Проверка видимости элемента
await expect(page.getByText('EXAMPLE')).toBeVisible();

У проверок Playwright есть ключевая особенность:автоматический повтор。

Если условие проверки временно не выполняется, Playwright будет продолжать повторять попытки, пока условие не будет выполнено или не истечёт время ожидания.

Это означает, что вам не нужно писатьwaitForилиsleepчтобы дождаться готовности страницы.


Шаблон async/await в тестах

Все операции Playwright асинхронны, поэтому тестовые функции должны быть объявлены какasync。

Все браузерные операции (goto、click、fillи т. д.) и утверждения (expect) должны использоватьawaitключевое слово (слова).

Пример

// Правильный способ
test('Correct example', async ({ page }) => {
  await page.goto('https://www.example.com/');
  await expect(page).toHaveTitle(/EXAMPLE/);
});

// Неправильный способ (отсутствует await)
test('Incorrect example', async ({ page }) => {
  page.goto('https://www.example.com/');        // Нет await!
  expect(page).toHaveTitle(/EXAMPLE/);           // Нет await!
});

Если вы забудете написатьawait, тест может выполнить проверку в неподходящий момент, что приведёт к нестабильности или случайным прохождениям. Обязательно добавляйте его каждый раз при вызове Playwright APIawait。


Понимание вывода теста

Давайте рассмотрим другой тест с неудачной проверкой, чтобы понять вывод теста:

Пример

// Путь к файлу: tests/fail-demo.spec.ts
import { test, expect } from '@playwright/test';

test('Намеренно падающий тест', async ({ page }) => {
  await page.goto('https://www.example.com/');

  // Проверяем, что заголовок содержит несуществующее содержимое; ожидается, что проверка не пройдёт
  await expect(page).toHaveTitle(/non-existent text/);
});

После запуска вывод выглядит примерно так:

Running 1 test using 1 worker

  ✘  1 [chromium] › tests/fail-demo.spec.ts:4:1 › 一个故意失败的测试 (5.2s)

  1 failed
    tests/fail-demo.spec.ts:4:1 › 一个故意失败的测试

Одновременно автоматически откроется HTML-отчёт, показывающий подробную информацию о сбое и снимки экрана с ошибками.

Другие расширения