Playwright Test
Помимо того, что Playwright является инструментом автоматизации браузера, он также поставляется сполноценным фреймворком для тестирования —— Playwright Test。
Playwright Test помогает организовывать тест-кейсы, генерировать отчёты, запускать параллельно, повторять при сбое и обладает всеми возможностями из коробки.
- Playwright Test — этовстроенная среда тестирования, не требующая дополнительных зависимостей.
- Файл конфигурации позволяет задаватьтаймаут, повторные попытки, отчёты, проекты браузерови т. д.
- Тест-кейсы поддерживаютгруппировку, хуки, data-driven。
- и обеспечиваютпараллельное выполнение, HTML-отчёты, повторные попытки при сбоеи другие продвинутые возможности.
Обзор тестового фреймворка
- Интегрированная среда тестирования: поставляется со встроенным тест-раннером, не нужно отдельно устанавливать Jest или Mocha.
- Встроенная библиотека утверждений: поддерживает
expectутверждения. - Изоляция тестов: каждый
testпо умолчанию запускается в новом контексте браузера, независимо друг от друга. - Богатые возможности: параллельное выполнение, повторные попытки, скриншоты, запись, HTML-отчёты и т. д.
Способ установки:
npm init playwright@latest
Автоматически создавать структуру проекта, включая файл конфигурацииplaywright.config.js。
1. Сведения о файле конфигурации
Playwright Test используетplaywright.config.js(или.ts) в качестве точки входа конфигурации.
// playwright.config.js
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests', // 测试目录
timeout: 30 * 1000, // 单个测试超时时间
retries: 2, // 失败重试次数
reporter: [['html'], ['list']], // 测试报告类型
use: {
headless: true, // 是否无头模式
screenshot: 'only-on-failure', // 失败时截图
video: 'retain-on-failure', // 失败时保留视频
baseURL: 'https://example.com', // 基础 URL
},
projects: [
{ name: 'Chromium', use: { browserName: 'chromium' } },
{ name: 'Firefox', use: { browserName: 'firefox' } },
{ name: 'WebKit', use: { browserName: 'webkit' } },
],
});
2. Структура тестового скрипта
Скрипты Playwright Test обычно включают:
1. Импорт библиотеки тестов
import { test, expect } from '@playwright/test';
2. Написание тест-кейсов
test('示例测试', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle('Example Domain');
});
3. Группировка и хуки
- Используйте
describeдля организации тестов - Используйте
beforeEach/afterEachдля настройки и завершения
Написание тест-кейсов
1. test()Использование функций
test('页面标题验证', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveTitle(/Playwright/);
});
2. describe()Группировка
test.describe('用户登录模块', () => {
test('输入正确账号密码', async ({ page }) => {
// 登录逻辑...
});
test('输入错误密码', async ({ page }) => {
// 验证错误提示...
});
});
3. Хуки тестов
test.describe('购物车模块', () => {
test.beforeEach(async ({ page }) => {
await page.goto('https://example.com/cart');
});
test.afterEach(async ({ page }) => {
await page.screenshot({ path: 'cart.png' });
});
test('添加商品', async ({ page }) => {
await page.click('#add-item');
await expect(page.locator('#cart-count')).toHaveText('1');
});
});
4. Подготовка тестовых данных
Поддерживает параметризованные тесты:
const users = [
{ name: 'admin', password: '123456' },
{ name: 'guest', password: 'guest' },
];
for (const user of users) {
test(`用户 ${user.name} 登录`, async ({ page }) => {
await page.goto('https://example.com/login');
await page.fill('#username', user.name);
await page.fill('#password', user.password);
await page.click('#submit');
await expect(page.locator('.welcome')).toBeVisible();
});
}
Запуск и отчётность
1. Команды выполнения тестов
npx playwright test # 运行全部测试 npx playwright test login.spec.js # 运行单个文件 npx playwright test -g "登录" # 运行指定用例
2. Параллельное тестирование
Playwright по умолчаниюзапускает файлы параллельно, или вы можете указать количество воркеров в файле конфигурации:
npx playwright test --workers=4
3. Генерация отчёта о тестировании
После запуска сгенерируйтеHTML-отчёт:
npx playwright show-report
4. Механизм повторных попыток при сбое
В файле конфигурацииplaywright.config.jsзадайте:
retries: 2
Когда тест завершается неудачей, он автоматически повторяется; это подходит для обработки перемежающихся ошибок.
- Playwright Test — этоинтегрированный фреймворк для тестирования, дополнительные зависимости не нужны.
- Файл конфигурации позволяет задаватьтаймаут, повторные попытки, отчёты, проекты браузерови т. д.
- Тест-кейсы поддерживаютгруппировку, хуки, data-driven。
- и обеспечиваютпараллельное выполнение, HTML-отчёты, повторные попытки при сбоеи другие продвинутые возможности.
Полный пример набора тестов
1. Структура проекта
playwright-demo/ ├─ playwright.config.ts # 全局配置(多项目、多浏览器、报告、重试…) ├─ package.json ├─ tests/ │ ├─ auth.setup.ts # 一次性登录,生成 storageState │ ├─ smoke/ │ │ └─ home.spec.ts # 冒烟用例:标题/URL/截图对比 │ └─ e2e/ │ └─ cart.spec.ts # 端到端:添加购物车、断言、附件、步骤 ├─ fixtures/ │ ├─ pages.ts # 页面对象(PO) │ └─ test.extend.ts # 自定义 fixtures └─ snapshots/ # 视觉基线(自动生成)
2. Файл конфигурации (playwright.config.ts)
Пример
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
timeout: 30_000,
retries: 2,
workers: 4,
reporter: [['html', { outputFolder: 'report' }], ['list']],
forbidOnly: !!process.env.CI,
// Единое использование по умолчанию (можно переопределить на уровне проекта или теста)
использовать: {
baseURL: 'https://demo.playwright.dev',
headless: true,
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'retain-on-failure',
viewport: { width: 1366, height: 900 },
locale: 'zh-CN',
},
// Несколько проектов: разные браузеры/устройства/состояния входа
projects: [
{ name: 'Chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'Firefox', use: { ...devices['Desktop Firefox'] } },
{
name: 'Mobile Chrome',
use: { ...devices['Pixel 7'], headless: истина },
},
// Проект с состоянием входа (повторное использование storageState)
{
name: 'Chromium Logged-in',
use: { storageState: 'storageState.json' },
dependencies: ['setup'], // Зависит от проекта 'setup' для генерации состояния входа
},
// Проект setup: запускается один раз для генерации storageState
{
name: 'setup',
testMatch: /auth\.setup\.ts/,
},
],
});
Ключевые моменты:проекты позволяют запускать один и тот же набор тестов в разных браузерах/конфигурациях; параметр use можно переопределить на глобальном уровне/уровне проекта/уровне теста; отчёты и повторные попытки управляются централизованно в конфигурации.
3. Фикстуры и Page Objects
fixtures/test.extend.ts (пользовательские фикстуры + инкапсуляция общих шагов)
Пример
import { test as base } from '@playwright/test';
import { HomePage, CartPage } from './pages';
type MyFixtures = {
home: HomePage;
cart: CartPage;
};
export const test = base.extend<MyFixtures>({
home: async ({ page }, use) => {
const home = new HomePage(page);
await use(home);
},
cart: async ({ page }, use) => {
const cart = new CartPage(page);
await use(cart);
},
});
export { expect } from '@playwright/test';
Добавьте пользовательские фикстуры на основе test.extend(), что позволяет легко напрямую внедрять экземпляры home и cart в любом тест-кейсе.
fixtures/pages.ts (объекты страниц)
Пример
import { Page, expect } from '@playwright/test';
export class HomePage {
constructor(private page: Page) {}
async goto() { await this.page.goto('/'); }
get tryTodoLink() { return this.page.getByRole('link', { name: /ToDo MVC/i }); }
}
export class CartPage {
constructor(private page: Page) {}
async goto() { await this.page.goto('/e2e'); } // Предполагается, что существует пример e2e-страницы
get addFirstItem() { return this.page.getByRole('button', { name: /Add .* #1/i }); }
get cartCount() { return this.page.locator('[data-test=cart-count]'); }
async addOne() { await this.addFirstItem.click(); }
async expectCount(n: number) { await expect(this.cartCount).toHaveText(String(n)); }
}
4. Предварительный вход (сгенерировать storageState один раз)
tests/auth.setup.ts (запускается только в проекте "setup")
Пример
import { test, expect } from '@playwright/test';
test('создать storageState', async ({ page }) => {
await page.goto('https://demo.playwright.dev/todomvc');
// ...Замените на ваш процесс входа...
// Предположим, что вход выполнен успешно
await expect(page).toHaveURL(/todomvc/);
await page.context().storageState({ path: 'storageState.json' });
});
5. Дымовые тесты (Заголовок/URL/Визуальное сравнение)
tests/smoke/home.spec.ts
Пример
test.describe('Дымовые - Главная', () => {
test('заголовок, URL и визуальный снимок', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveTitle(/Playwright/);
await expect(page).toHaveURL(/playwright\.dev/);
// Визуальная регрессия (автосоздание/сравнение базового снимка)
await expect(page).toHaveScreenshot(); // Первый запуск создаёт базовый снимок
});
});
Для визуального сравнения рекомендуется использовать toHaveScreenshot (предпочтительнее ручного подхода с использованием page.screenshot() + toMatchSnapshot).
6. Сквозные тесты (шаги, вложения, проверки)
tests/e2e/cart.spec.ts
Пример
test.describe.configure({ mode: 'parallel' });
test.describe('E2E - Корзина', () => {
test.beforeEach(async ({ home }) => {
await test.step('Перейти на главную страницу', async () => {
await home.goto();
});
});
test('Добавить товар в корзину (с вложением и проверкой)', async ({ page, cart }) => {
await test.step('Перейти на страницу корзины и добавить товар', async () => {
await cart.goto();
await cart.addOne();
await cart.expectCount(1);
});
await test.step('Прикрепить отладочную информацию к отчёту', async () => {
await test.info().attach('state.json', {
contentType: 'application/json',
body: Buffer.from(JSON.stringify({ ts: Date.now(), note: 'после добавления' })),
});
});
// Скриншот элемента
await test.step('Скриншот элемента', async () => {
const badge = page.locator('[data-test=cart-count]');
await expect(badge).toBeVisible();
await expect(badge).toHaveScreenshot(); // Снимок элемента
});
});
});
Используйте test.step для иерархической записи шагов, а test.info().attach() — для прикрепления отладочных данных/скриншотов к отчёту для упрощения диагностики; в параллельном режиме можно использовать describe.configure({ mode: 'parallel' }).
7. Запуск и отчётность
Основные команды:
npx playwright test # 运行全部 npx playwright test tests/e2e # 运行目录 npx playwright test -g "Cart" # 按标题过滤 npx playwright test --project="Chromium" # 指定项目 npx playwright show-report # 打开HTML报告 npx playwright test --update-snapshots # 更新视觉基线 npx playwright test --debug # 调试模式(Inspector)
Для фильтрации в CLI, выбора проекта, просмотра отчётов, обновления снимков и т.д. см. официальную документацию по CLI/Reporting/Snapshot.
Краткий справочник по общим связанным API (Playwright Test)
1. Тесты и группировка
| API | Назначение |
|---|---|
test(name, fn) |
Определение тестов |
test.describe(title, fn) |
Группировка |
test.describe.configure({ mode }) |
parallel / serial |
test.beforeAll/afterAll |
Хуки before/after на уровне группы |
test.beforeEach/afterEach |
Хуки before/after тест-кейса |
test.skip/only/fixme/slow/fail |
Отметка/управление тест-кейсами |
2. Фикстуры и конфигурация
| API | Назначение |
|---|---|
test.extend<Fixtures>(defs) |
Расширение пользовательских фикстур |
test.use(options) |
Переопределение на уровне тестаuseОпции (такие какstorageState、viewport、localeи т.д.) |
defineConfig({...}) |
Запись в файле конфигурации (testDir、retries、workers、reporter…) |
projects |
Запуск нескольких проектов/браузеров/разных конфигураций |
use: { baseURL, trace, video, screenshot, viewport, locale, timezoneId, storageState } |
Среда выполнения и стратегия захвата |
Подробнее о фикстурах / опции use / параметрах конфигурации и проектах см. в официальной документации "Fixtures / Use options / Configuration / Projects". (Playwright)
3. Утверждения (expect)
| API | Назначение | |
|---|---|---|
expect(value).toBe / toEqual / toContain ... |
Общие утверждения | |
expect(locator).toHaveText/Value/Attribute |
Веб-специфичные утверждения (с умным ожиданием) | |
expect(locator).toBeVisible/Hidden/Enabled/Disabled/Checked |
Утверждения состояния | |
expect(page).toHaveTitle/URL |
Утверждения страницы | |
| `expect(page/locator).toHaveScreenshot([name | options])` | Сравнение визуальных снимков (рекомендуется) |
Рекомендации по утверждениям и визуальным снимкам см. в документации Assertions and Snapshots.(Playwright)
4. Шаги и вложения
| API | Назначение | |
|---|---|---|
test.step(name, fn) |
Разбивайте тесты на шаги (визуализация в отчёте) | |
| `test.info().attach(name, { path | body, contentType })` | Прикрепляйте файлы/данные к тестам или шагам (отображается в отчёте) |
Вложения также можно применять на уровне шага (см. TestStep / TestStepInfo).(Playwright)
5. Отчётность и CLI
| Команда/Конфигурация | Назначение |
|---|---|
reporter: [['html', { outputFolder }], ['list']] |
Конфигурация отчёта |
npx playwright test --project="Chromium" |
Выберите проект для запуска |
-g "keyword" / --grep / --grep-invert |
Фильтровать тест-кейсы |
--update-snapshots |
Обновить визуальные эталоны |
npx playwright show-report |
Открыть отчёт |
Другие расширенияСмотрите официальную документацию для полного списка параметров CLI и Reporter.(Playwright)