Параллелизм внутри файла

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

Запуск нескольких тестов в одном файле

В Playwright можно запускать несколько тестов одновременно, используя несколько подходов. Один из самых простых и распространенных способов — это использование фреймворка для тестирования, например, Jest или Mocha, который поддерживает параллельное выполнение тестов.

Playwright имеет встроенную поддержку параллелизма через механизм параллельного выполнения тестов с использованием Test Runner. Этот подход позволяет разбивать тесты на несколько потоков и выполнять их одновременно, что значительно сокращает время, затраченное на тестирование.

Основы настройки параллелизма

В Playwright используется объект test.describe.parallel(), который позволяет разделить тесты на параллельные блоки. Все тесты, определенные внутри test.describe.parallel(), будут выполнены параллельно.

Пример использования параллелизма в одном файле:

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

test.describe.parallel('Тесты для страницы авторизации', () => {
  test('Тест 1: Проверка успешного входа', async ({ page }) => {
    await page.goto('https://example.com/login');
    await page.fill('#username', 'user');
    await page.fill('#password', 'password');
    await page.click('#login-button');
    await expect(page).toHaveURL('https://example.com/dashboard');
  });

  test('Тест 2: Проверка ошибки при неверных данных', async ({ page }) => {
    await page.goto('https://example.com/login');
    await page.fill('#username', 'wronguser');
    await page.fill('#password', 'wrongpassword');
    await page.click('#login-button');
    await expect(page.locator('.error-message')).toBeVisible();
  });
});

В этом примере два теста для страницы авторизации запускаются параллельно. Первый тест проверяет успешный вход, а второй — обработку ошибки при неверных данных. Оба теста выполняются одновременно, что ускоряет процесс тестирования.

Управление количеством параллельных потоков

Хотя параллельное выполнение тестов существенно ускоряет процесс тестирования, важно учитывать, что чрезмерное количество потоков может привести к перегрузке системы и ухудшению производительности. Для управления количеством параллельных потоков в Playwright используется настройка в конфигурационном файле playwright.config.ts.

Пример конфигурации:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  workers: 4, // Устанавливаем 4 параллельных потока
});

Здесь параметр workers указывает, сколько потоков будет использоваться для выполнения тестов. Это значение можно настроить в зависимости от доступных ресурсов и количества тестов. Если тестов много, но система ограничена по ресурсам, можно уменьшить число потоков для предотвращения перегрузки.

Параллелизм в контексте разных браузеров

В Playwright можно настроить параллельное выполнение тестов не только внутри одного браузера, но и для разных браузеров одновременно. Это особенно полезно для тестирования кросс-браузерной совместимости. Playwright поддерживает работу с Chrome, Firefox и WebKit, и можно настроить выполнение тестов для каждого из этих браузеров параллельно.

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

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

test.describe.parallel('Кросс-браузерные тесты', () => {
  test('Тест для Chrome', async ({ page }) => {
    const browser = await browsers.chromium.launch();
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('https://example.com');
    await expect(page.locator('h1')).toHaveText('Example Domain');
    await browser.close();
  });

  test('Тест для Firefox', async ({ page }) => {
    const browser = await browsers.firefox.launch();
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('https://example.com');
    await expect(page.locator('h1')).toHaveText('Example Domain');
    await browser.close();
  });

  test('Тест для WebKit', async ({ page }) => {
    const browser = await browsers.webkit.launch();
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('https://example.com');
    await expect(page.locator('h1')).toHaveText('Example Domain');
    await browser.close();
  });
});

В этом примере три теста выполняются параллельно для разных браузеров. Каждый тест проверяет загрузку страницы в своем браузере, что позволяет проверить совместимость приложения с несколькими платформами одновременно.

Синхронизация тестов

При использовании параллельного выполнения тестов важно учитывать, что тесты должны быть независимыми. Это означает, что результаты одного теста не должны зависеть от состояния системы, оставленного другим тестом. Однако в некоторых случаях может возникнуть необходимость синхронизировать тесты для взаимодействия с общими ресурсами, например, базой данных или сервером.

Playwright предоставляет возможности для синхронизации тестов с помощью семафоров, блокировок или общих переменных. Одним из способов синхронизации является использование функции beforeAll или afterAll, которая выполняется до или после всех тестов.

Пример использования синхронизации с beforeAll:

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

test.describe.parallel('Тесты с синхронизацией', () => {
  let sharedResource;

  test.beforeAll(async () => {
    // Инициализация общих ресурсов перед запуском тестов
    sharedResource = await initializeResource();
  });

  test('Тест 1: Использование общего ресурса', async () => {
    const result = await sharedResource.someOperation();
    expect(result).toBeTruthy();
  });

  test('Тест 2: Другой тест с общим ресурсом', async () => {
    const result = await sharedResource.anotherOperation();
    expect(result).toBeFalsy();
  });
});

В данном примере общий ресурс инициализируется в методе beforeAll и используется в нескольких тестах. Это гарантирует, что ресурс будет доступен для всех тестов, и одновременно позволяет контролировать порядок выполнения операций.

Отладка параллельных тестов

Когда тесты выполняются параллельно, отладка может стать более сложной, так как порядок их выполнения не всегда предсказуем. Чтобы упростить отладку, Playwright позволяет записывать логи и делать скриншоты или видео для каждого теста.

Включение видеозаписи и логирования:

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

test.describe.parallel('Тесты с видео и логами', () => {
  test('Тест с видео', async ({ page }) => {
    await page.context().tracing.start({ screenshots: true, snapshots: true });
    await page.goto('https://example.com');
    await page.click('text=More information');
    await page.context().tracing.stop({ path: 'trace.zip' });
  });
});

В этом примере для каждого теста будет записан видеофайл, содержащий все действия на странице, а также будет сохранен файл с трассировкой, который можно использовать для последующего анализа.

Заключение

Параллелизм внутри одного файла тестов в Playwright — мощный инструмент для ускорения тестирования и повышения эффективности работы с большим количеством сценариев. Он позволяет одновременно запускать несколько тестов в разных браузерах, с различными конфигурациями и независимыми состояниями. Важно учитывать правильную настройку количества потоков, независимость тестов и возможную необходимость синхронизации для успешного использования параллелизма в тестах.