# Параллельное тестирование

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

## Определение

**Параллельное тестирование (Parallel Testing)** — одновременный запуск нескольких тестов или наборов тестов в независимых процессах или потоках с целью сокращения общего времени прогона.

Не путать с **параллельным тестированием как методом** (запуск новой и старой системы параллельно для сравнения результатов — это отдельная практика).

## Стратегии параллелизации

### По файлу (file-level parallelism)

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

### По тесту (test-level parallelism)

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

### По окружению (environment matrix)

Один и тот же набор тестов запускается параллельно в разных конфигурациях: разные браузеры, ОС, версии Node.js. В GitHub Actions реализуется через `strategy.matrix`.

### Sharding (разбивка suite на части)

Suite разбивается на N статических частей, каждая запускается на отдельном CI-воркере. Уменьшает clock time пропорционально числу shards. При 4 shards — \~4× ускорение.

## Нативный sharding в фреймворках

Большинство современных фреймворков поддерживают sharding без дополнительных зависимостей:

| Фреймворк      | Команда                           | Версия              |
| -------------- | --------------------------------- | ------------------- |
| **Playwright** | `npx playwright test --shard=2/4` | Любая               |
| **Vitest**     | `vitest run --shard=2/4`          | Любая               |
| **Jest**       | `jest --shard=2/4`                | v28+                |
| **pytest**     | `pytest --splits 4 --group 2`     | pytest-split плагин |

Пример GitHub Actions matrix для Playwright:

```yaml
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1/4, 2/4, 3/4, 4/4]
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test --shard=${{ matrix.shard }}
```

## Динамическое распределение тестов

Статический sharding делит тесты поровну по числу. Динамическое распределение — более умный подход: тесты распределяются по воркерам с учётом исторического времени выполнения, чтобы воркеры завершали работу одновременно.

**Currents.dev** — платформа оркестрации для Playwright и Cypress с динамическим балансированием.

**Sorry Cypress** — open-source альтернатива для Cypress.

## Проблемы параллельного запуска

### Shared state (общее состояние)

Тесты, изменяющие общие тестовые данные (один пользователь, одна запись в БД), конфликтуют при параллельном запуске. Решение: каждый тест создаёт собственные данные или использует уникальные идентификаторы.

### Race conditions

Параллельные записи в одну таблицу БД могут вызвать конфликты уникальности или нарушение порядка операций. Решение: изолировать БД на уровне схемы или транзакции.

### Изоляция базы данных

Подходы к изоляции при параллельных тестах:

* **Отдельная БД на воркер** — каждый воркер поднимает свою БД через Testcontainers
* **Транзакционный rollback** — тест оборачивает операции в транзакцию, откатывает после
* **Шаблонная БД** — быстрое создание копии из шаблона (PostgreSQL `CREATE DATABASE ... TEMPLATE`)
* **Tenant-изоляция** — каждый воркер работает в своём namespace/schema

### Конфликты портов

Если тесты поднимают локальный сервер, каждый воркер должен получить свой порт. В Playwright это решается автоматически через `webServer` конфигурацию с `reuseExistingServer: false`.

## Cloud execution

Для крупных суитов или cross-browser параллелизма используют облачные платформы:

| Платформа                 | Особенность                                    |
| ------------------------- | ---------------------------------------------- |
| **BrowserStack Automate** | 20 000+ реальных устройств и браузеров         |
| **LambdaTest**            | Выгодная цена, HyperExecute для параллелизации |
| **Sauce Labs**            | Enterprise compliance, SOC2/ISO 27001          |
| **GitHub Actions**        | До 20 параллельных воркеров на план            |

## Отчётность при sharding

При разбивке на shards каждый воркер создаёт свой отчёт. Для получения единого HTML-отчёта Playwright предоставляет команду merge:

```bash
# Объединить blob-репорты из всех shards в HTML
npx playwright merge-reports --reporter html ./all-blob-reports
```

## Источники

* [Playwright: Parallelism and sharding](https://playwright.dev/docs/test-parallel)
* [Vitest: test sharding](https://vitest.dev/guide/improving-performance#sharding)
* [Jest: `--shard` flag](https://jestjs.io/docs/cli#--shard)
* [Currents.dev — parallel test orchestration](https://currents.dev)
* [Testcontainers: database isolation patterns](https://testcontainers.com/guides/testing-spring-boot-rest-api-using-testcontainers/)

### Дополнительные материалы

* [Parallel testing: get feedback earlier, release faster](https://medium.com/azimolabs/parallel-testing-get-feedback-earlier-release-faster-b66d4dd08930) — практические советы по переходу на параллельный запуск
* [Ускоряем прохождение iOS UI-тестов. Параллелизация](https://habr.com/ru/company/vivid_money/blog/652397/) — кейс на iOS с конкретными цифрами ускорения


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://vladislaveremeev.gitbook.io/qa_bible/avtomatizaciya-testirovaniya/tekhniki-i-patterny/parallelnoe-testirovanie-parallel-testing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
