DEV Community

Aykut Denizci
Aykut Denizci

Posted on • Originally published at aykutdenizci.Medium on

Sharding in Playwright: Speeding Up Your Test Suites and CI Pipelines

Ai Generated Image For Sharding Expression

In this article, I’ll talk about why using sharding in Playwright automation projects is so important, how it affects your test durations, and how you can use it effectively based on your project needs.

By default, Playwright runs test files in parallel and strives for optimal utilization of CPU cores on your machine.

To achieve even greater parallelization, you can further scale Playwright test execution by running tests on multiple machines simultaneously — a process Playwright refers to as “sharding.”

Without sharding, all tests are distributed among the workers within a single pod.

When sharding is enabled, the test suite is divided into multiple shards, and each shard runs its own workers on separate pods.

This allows true multi pod parallelism.

  • Workers → parallel test executors within the same pod
  • Shards → distribute the test suite across multiple pods

To enable sharding, simply add the following option to the end of your test command.

Here, x represents the active shard index, and y represents the total number of shards:

--shard=x/y
Enter fullscreen mode Exit fullscreen mode

If you’re using sharding, the fullyParallel parameter becomes even more important.

When this parameter is set to true, all your tests are divided and executed across the shards.

If it’s set to false, the distribution happens on a file basis — meaning entire test files are assigned to shards rather than individual tests.

However, there’s an important nuance here: even when fullyParallel is set to false, the same test file can still run on different shards if it’s executed under multiple projects defined in your Playwright configuration.

For example, a basket1.spec.ts file might run on one shard for the project1 project and on another shard for the project2 project.

You can add sharding to your YAML configuration as shown below:

parallel: 4
  script:
    - npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
Enter fullscreen mode Exit fullscreen mode

Tip: If you’re using npm run or yarn run, you need to add an extra -- before your Playwright arguments.

npm run test -- --shard=1/4
Enter fullscreen mode Exit fullscreen mode

In our automation project, we built a login system that assigns different users to each worker within a spec file to prevent them from interfering with one another.

However, this setup introduced flakiness in our tests when running with Playwright’s fullyParallel parameter — both in true and false modes.

To overcome this issue, we started manually assigning spec files to specific shards , giving us full control over how tests are distributed.

If you’re facing a similar problem, you can configure your YAML file as shown below.

parallel:
    matrix:
      - SPEC_FILE: "basket1.spec.ts basket2.spec.ts"
      - SPEC_FILE: "basket3.spec.ts checkout.spec.ts checkout2.spec.ts"
      - SPEC_FILE: "checkout3.spec.ts basket4.spec.ts"
      - SPEC_FILE: "checkout4.spec.ts"  
Enter fullscreen mode Exit fullscreen mode

When doing so, it’s important to keep the completion times of shards as close as possible to optimize the overall pipeline duration.

If one spec file takes significantly longer than others, consider splitting it into multiple smaller specs and assigning them to different shards — this can lead to a noticeable time gain.

For example, in our project, the checkout4.spec.ts file used to take much longer than other specs.

By splitting it into two separate specs and assigning them to different shards, we were able to significantly reduce the total test duration.

Before

Test Step Before Sharding

After

Test Step After Sharding

After completing the sharding setup, the next important step is merging the reports generated by the shards.

To merge the reports, you need to set the reporter type in your Playwright configuration to blob.

The blob reporter is mergeable and can be converted into other reporting formats. It can include screenshots, traces, and other attachments , making it ideal for shard-based parallel test runs.

You can add the following setting to your configuration file:

export default defineConfig({
  testDir: './tests',
  reporter: process.env.CI ? 'blob' : 'html',
});
Enter fullscreen mode Exit fullscreen mode

To merge your reports, you can run the following command:

npx playwright merge-reports --reporter html ./all-blob-reports
Enter fullscreen mode Exit fullscreen mode

Here, the --reporter parameter specifies which format the blob reports will be converted to , and the path at the end points to the folder containing the blob reports to merge.

Additionally, if you have multiple reporting configurations or want to generate multiple report types from blob reports, you can create a separate config file and pass it to the merge-reports command.

For example, in our project, we generate both HTML and Allure reports.

Here’s the merge.config.ts we use:

export default {
    testDir: 'tests',
    reporter: [['html', { open: 'never' }], 
    ['allure-playwright', {
        outputFolder: "allure-results",
      }],
      ['json', { outputFile: 'playwright-report/test-results.json' }]],
  };
Enter fullscreen mode Exit fullscreen mode

You can then use this config file in the merge step as follows:

npx playwright merge-reports --config merge.config.ts ./blob-report
Enter fullscreen mode Exit fullscreen mode

After completing the merging step, let’s look at how sharding improved our test durations in the project.

In our automation project, we divide our tests into different schedules based on tags for example, schedule1, schedule2, and so on. The impact of our sharding structure on these schedules is shown in the table below.

Impact of Sharding on Our Project (Table)

Thanks for the readings 🎭

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.