«В этой небольшой статье мы рассмотрим, как применять функцию шардинга в Playwright для разделения тестов по частям-шардам, чтобы ускорить выполнение и сократить время обратной связи в CI. Но сначала хочу обсудить параллелизм в Playwright.
Параллелизм
В Playwright предусмотрен параллельный запуск тестов, и по умолчанию в файле playwright.config.js
установлено значение true. При включении этой опции запускается несколько worker-процессов, выполняющихся одновременно. Тесты в одном файле запускаются последовательно в одном worker-процессе.

Параллельные тесты выполняются в отдельных рабочих процессах и могут не иметь общих состояний или общих глобальных переменных.
Существует несколько способов настроить параллельное выполнение тестов.
- Использование
test.describe.configure({ mode: 'parallel' });
- Также можем использовать
fullyParallel: true
, чтобы включить параллельность для всех тестов - Или включить
fullyParallel: true
для некоторых проектов, например chromium, firefox, webkit и т. д.
Чтобы отключить этот параллелизм, мы можем настроить запуск тестов с использованием только одного worker-а, через конфигурационный файл, установив для worker-ов значение 1, или передать то же самое из командной строки: npx playwright test — workers=1.
Подробнее о параллельном запуске — на сайте Playwright.
Что такое шардинг
Sharding происходит от концепции архитектуры баз данных, в которой мы разбиваем большую базу данных на несколько «кусков» или шардов, чтобы распределить и оптимизировать нагрузку, повысить эффективность и масштабируемость системы. Это можно назвать горизонтальным масштабированием, когда каждый шард ведет себя как независимая единица со своими собственными ресурсами и управляет данными соответствующим образом. Таким образом улучшается производительность запросов и устраняются точки отказа при использовании отдельного сервера базы данных, который обрабатывает огромные объемы данных.
Подробнее о шардинге здесь, а также замечательное видео.
Теперь, перейдя в мир Playwright, мы можем использовать концепцию шардинга для ускорения выполнения тестов путем разделения этих тестов по отдельным шардам, то есть машинам. Мы можем сделать это с помощью параметра shard
, то есть shard=x/y
, где x
— индекс-shard, а y
— общее количество шардов.
npx playwright test --shard=1/4 npx playwright test --shard=2/4 npx playwright test --shard=3/4 npx playwright test --shard=4/4
В данном случае мы разделили тесты на 4 шарда, поэтому указанное в конфигурации количество worker-ов будет работать с каждым из этих блоков, сокращая общее время выполнения.
Для демонстрационных целей я установил Playwright на локальной машине и буду использовать пример boilerplate-кода, представленный в папке tests-examples
, где у нас есть несколько тестов, которые настроены для запуска на сайте playwright to-do mvc (URL: https://demo.playwright.dev/todomvc )
Здесь у нас 24 теста, которые запускаются на 3 браузерах, поэтому в целом 72 теста для одного файла, я скопировал один и тот же файл дважды, поэтому с 3 файлами спецификаций у нас 216 тестов в 3 браузерах — chromium, firefox и webkit. Я переименовал файлы спецификаций, как показано ниже.

В файле playwright.config.js
я задал следующие конфигурации, установив значение parallel
в true
и значение workers
в 6.
fullyParallel: true workers: process.env.CI ? 6 : 6
Это означает, что когда я выполню команду: npx playwright test
, все 216 тестов будут запущены 6 worker-ами локально и в CI. Приведенные ниже тесты выполняются на локальной машине с использованием 6 worker-ов.

Теперь, когда я выполню команду npx playwright test
вместе с параметром shard
, указав общее количество шардов как 4, то сначала 216 тестов будут разделены на 4 куска по 54 теста в каждом. Затем эти 54 теста будут выполнены с помощью 6 worker-а в шарде 1, 54 теста с помощью 6 worker-ов в шарде 2, как показано ниже. Поскольку каждый шард будет выполняться на своей собственной машине-агенте, уровень параллелизма будет гораздо выше, и наши тесты будут выполняться значительно быстрее, чем при использовании 6 worker-ов в стандартной конфигурации.

Но с шардингом мы столкнулись с проблемой при создании репортов (с помощью стандартной опции html-репорта). После выполнения теста, выполнив команду ‘npx playwright show-report
‘, мы увидим, что в сгенерированном отчете будут показаны только результаты последнего запущенного шарда, содержащего всего 54 теста, как показано ниже. А как быть с остальными, в предыдущих шардах?

Чтобы решить эту проблему, нам нужно сконфигурировать наш репортер как ‘blob’, когда мы используем шардинг. По умолчанию каждый шард будет генерировать свои собственные blob-репорты в папку под названием blob-report. Затем нам нужно будет объединить все эти отдельные blob-репорты со всех шардов, чтобы получить консолидированный репорт по всем тестам, которые были выполнены на всех шардах.
export default defineConfig({ reporter: process.env.CI ? 'blob' : 'html' });
Чтобы объединить репорты из нескольких шардов, поместите файлы blob-репортов в один каталог, например, в нашем случае all-blob-reports, тогда окончательный HTML-репорт будет доступен в папке playwright-report.
npx playwright merge-reports --reporter html ./all-blob-reports
Шардинг в CI с помощью Github Actions
Теперь, чтобы еще эффективнее использовать шардинг, применим такие инструменты CI, как Github Actions, которые позволяют удобно настраивать и запускать тесты на нескольких машинах-агентах. Для этого нам нужно включить следующие пункты в наш файл рабочего процесса Github actions:
- Добавление стратегии с опцией
matrix
в задачу со значениямиshardIndex
иshardTotal
. - Запуск команды
npx playwright test
с указанием параметровshardindex
иshardTotal
. - Загрузить блоб-репорт отдельных шардов в артефакты Github actions, чтобы задача merge-report могла подхватить его и сгенерировать консолидированный HTML-отчет.
name: Sharding Tests on: push: branches: [ main, master ] pull_request: branches: [ main, master ] jobs: run-tests: timeout-minutes: 60 runs-on: ubuntu-latest strategy: fail-fast: false matrix: shardIndex: [1, 2, 3, 4, 5, 6 ] shardTotal: [6] steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 20 - name: Install dependencies run: npm ci - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Run Playwright tests run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - name: Upload blob report to GitHub Actions Artifacts if: always() uses: actions/upload-artifact@v4 with: name: blob-report-${{ matrix.shardIndex }} path: blob-report retention-days: 1
Для задачи «run-tests
» мы будем использовать в общей сложности 6 шардов, указанных в matrix
, с параметром fail-fast
, установленным на false
. Затем мы выполним npx playwright test
, используя определенные значения shardIndex
и shardTotal
, например 1/6, 2/6 и т. д. Наконец, когда все шарды будут выполнены, blob-репорты по каждому шарду будут загружены в артефакты Actions в разделе blob-report с суффиксом shardIndex
.
Далее нам нужно добавить задачу «merge-reports
«, которая будет зависеть от задачи run-tests
. Эта задача будет загружать все отдельные blob-репорты шардов в указанную папку под названием all-blob-reports
, а затем выполнять команду merge-reports
, чтобы получить объединенный HTML-репорт и загрузить его на вкладку GitHub Actions Artifacts.
merge-reports: if: always() needs: [run-tests] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 18 - name: Install dependencies run: npm ci - name: Download blob reports from GitHub Actions Artifacts uses: actions/download-artifact@v4 with: path: all-blob-reports pattern: blob-report-* merge-multiple: true - name: Merge into HTML Report run: npx playwright merge-reports --reporter html ./all-blob-reports - name: Upload HTML report uses: actions/upload-artifact@v4 with: name: html-report--attempt-${{ github.run_attempt }} path: playwright-report retention-days: 7
Вот мой полный файл workflow вместе с задачами:
name: Playwright tests using sharding on: push: branches: [ main, master ] pull_request: branches: [ main, master ] jobs: run-tests: timeout-minutes: 60 runs-on: ubuntu-latest strategy: fail-fast: false matrix: shardIndex: [1, 2, 3, 4, 5, 6 ] shardTotal: [6] steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 20 - name: Install dependencies run: npm ci - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Run Playwright tests run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - name: Upload blob report to GitHub Actions Artifacts if: always() uses: actions/upload-artifact@v4 with: name: blob-report-${{ matrix.shardIndex }} path: blob-report retention-days: 1 merge-reports: if: always() needs: [run-tests] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 18 - name: Install dependencies run: npm ci - name: Download blob reports from GitHub Actions Artifacts uses: actions/download-artifact@v4 with: path: all-blob-reports pattern: blob-report-* merge-multiple: true - name: Merge into HTML Report run: npx playwright merge-reports --reporter html ./all-blob-reports - name: Upload HTML report uses: actions/upload-artifact@v4 with: name: html-report--attempt-${{ github.run_attempt }} path: playwright-report retention-days: 7
Как только файл workflow будет отправлен на Github, все тесты (216) будут распределены и запущены на определенных машинах шарда, в нашем случае на 6 машинах. Как видно ниже, 36 тестов выполняются на машине run-tests
(1,6). Аналогично 36 тестов будут выполнены с помощью 6 worker-ов на другой машине шарда. После выполнения всех тестов будет запущена задача слияния репортов, которая сгенерирует консолидированный HTML-репорт.


Ниже приведены артефакты, которые были загружены в рамках выполнения workflow: индивидуальный блоб-репорт по шардам и итоговый консолидированный html-репорт.

Загрузив и открыв репорт, вы обнаружите полный отчет о прогоне тестов, содержащий 216 тестов, выполненных на 6 шард-машинах.

Вот что умеет Playwright. Спасибо за прочтение и надеемся, что эта статья была вам полезна.»
Официальная документация Playwright