Facebook

Course Name Start Date Time Duration Registration Link
No Training Programs Scheduled ClickHere to Contact
Please mail To sudhakar@qtpsudhakar.com to Register for any training

Thursday, August 21, 2025

Mastering Playwright Test Sharding: A Complete Guide to Parallel and Distributed Test Execution

Playwright Sharding Article

Ever wondered how Playwright achieves distributed execution without the grid and node concepts that were foundational in Selenium? While we execute Selenium, Playwright, or any other tests through CI/CD systems, Playwright has simplified distributed execution by working with existing infrastructure rather than building its own.

As modern web applications grow in complexity, so does the need for comprehensive test suites. While thorough testing is essential for quality assurance, it can significantly slow down development cycles when test execution takes too long. This is where Playwright test sharding becomes a game-changer, enabling teams to distribute tests across multiple machines and dramatically reduce execution time.

⚡ The Purpose of Distributed and Parallel Execution

Before diving into the differences, let's understand why distributed and parallel execution matters:

Parallel Execution Benefits:

  • Local Speed: Run multiple tests simultaneously on the same machine using multiple CPU cores
  • Resource Optimization: Better utilization of available CPU and memory on a single machine
  • File-level Distribution: Different test files run concurrently while maintaining isolation
  • graph TB subgraph "Single Machine - Parallel" CPU[๐Ÿ–ฅ️ CPU with 4 cores] CPU --> W1[๐Ÿ”„ Worker 1
    test1.spec.js] CPU --> W2[๐Ÿ”„ Worker 2
    test2.spec.js] CPU --> W3[๐Ÿ”„ Worker 3
    test3.spec.js] CPU --> W4[๐Ÿ”„ Worker 4
    test4.spec.js] end style CPU fill:#e1f5fe,stroke:#0277bd,stroke-width:2px style W1 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style W2 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style W3 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style W4 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px

    Distributed Execution Benefits:

  • Horizontal Scaling: Spread tests across multiple machines for massive speed improvements
  • Reduced Test Time: Instead of running 1000 tests sequentially in 60 minutes, distribute them across 4 machines to complete in ~15 minutes
  • CI/CD Efficiency: Leverage multiple CI agents/runners simultaneously
  • Faster Feedback: Get test results quickly to accelerate development cycles
  • True Scalability: Handle growing test suites without proportionally increasing execution time
  • graph TB subgraph "Distributed Execution" M1[๐Ÿ–ฅ️ Machine 1
    Shard 1/4
    Tests 1-250] M2[๐Ÿ–ฅ️ Machine 2
    Shard 2/4
    Tests 251-500] M3[๐Ÿ–ฅ️ Machine 3
    Shard 3/4
    Tests 501-750] M4[๐Ÿ–ฅ️ Machine 4
    Shard 4/4
    Tests 751-1000] end M1 --> R1[๐Ÿ“Š Results 1] M2 --> R2[๐Ÿ“Š Results 2] M3 --> R3[๐Ÿ“Š Results 3] M4 --> R4[๐Ÿ“Š Results 4] R1 --> MR[๐Ÿ“‹ Merged Report] R2 --> MR R3 --> MR R4 --> MR style M1 fill:#e8f5e8,stroke:#2e7d32,stroke-width:3px style M2 fill:#e8f5e8,stroke:#2e7d32,stroke-width:3px style M3 fill:#e8f5e8,stroke:#2e7d32,stroke-width:3px style M4 fill:#e8f5e8,stroke:#2e7d32,stroke-width:3px style R1 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style R2 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style R3 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style R4 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style MR fill:#fce4ec,stroke:#c2185b,stroke-width:3px

    Combined Impact:

    When you combine both approaches, you can run tests in parallel on each machine AND distribute those parallel executions across multiple machines, achieving maximum speed and efficiency.

    ๐Ÿ” What is Parallel Execution and Sharding in Playwright?

    Understanding Parallelism in Playwright

    Playwright Test runs tests in parallel by default, utilizing multiple worker processes that run simultaneously. By default, test files are run in parallel, while tests within a single file are executed in order within the same worker process.

    graph LR subgraph "Playwright Parallelism" subgraph "File-level" F1[๐Ÿ“„ test1.spec.js] F2[๐Ÿ“„ test2.spec.js] F3[๐Ÿ“„ test3.spec.js] F4[๐Ÿ“„ test4.spec.js] end subgraph "Test-level" T1[๐Ÿงช test login] T2[๐Ÿงช test checkout] T3[๐Ÿงช test profile] T4[๐Ÿงช test search] end subgraph "Project-level" P1[๐ŸŒ Chromium Project] P2[๐ŸฆŠ Firefox Project] P3[๐ŸŽ WebKit Project] end end style F1 fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style F2 fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style F3 fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style F4 fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style T1 fill:#f1f8e9,stroke:#689f38,stroke-width:2px style T2 fill:#f1f8e9,stroke:#689f38,stroke-width:2px style T3 fill:#f1f8e9,stroke:#689f38,stroke-width:2px style T4 fill:#f1f8e9,stroke:#689f38,stroke-width:2px style P1 fill:#fef7e0,stroke:#f9a825,stroke-width:2px style P2 fill:#fef7e0,stroke:#f9a825,stroke-width:2px style P3 fill:#fef7e0,stroke:#f9a825,stroke-width:2px

    There are three levels of parallelism in Playwright:

  • File-level parallelism (default): Different test files run in parallel, but tests within each file run sequentially
  • Test-level parallelism: Individual tests within files can run in parallel using test.describe.configure()
  • Project-level parallelism: Using testProject.fullyParallel or testConfig.fullyParallel
  • How Playwright Workers Enable Parallelism

    Playwright achieves parallelism through worker processes. Each worker is an independent OS process that runs a subset of your tests:

    graph TB subgraph "Single Machine Parallelism" TestRunner[๐ŸŽญ Playwright Test Runner] Worker1[⚙️ Worker 1
    Process ID: 1234
    Running: login.spec.js] Worker2[⚙️ Worker 2
    Process ID: 1235
    Running: checkout.spec.js] Worker3[⚙️ Worker 3
    Process ID: 1236
    Running: profile.spec.js] Worker4[⚙️ Worker 4
    Process ID: 1237
    Running: search.spec.js] TestRunner --> Worker1 TestRunner --> Worker2 TestRunner --> Worker3 TestRunner --> Worker4 Worker1 --> Browser1[๐ŸŒ Browser Instance 1] Worker2 --> Browser2[๐ŸŒ Browser Instance 2] Worker3 --> Browser3[๐ŸŒ Browser Instance 3] Worker4 --> Browser4[๐ŸŒ Browser Instance 4] end style TestRunner fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px style Worker1 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Worker2 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Worker3 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Worker4 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Browser1 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px style Browser2 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px style Browser3 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px style Browser4 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px

    Key characteristics of Playwright workers:

  • Isolated processes: Each worker runs in its own OS process for complete isolation
  • Independent browsers: Each worker starts its own browser instance
  • No communication: Workers cannot communicate with each other
  • Automatic assignment: Playwright automatically distributes test files to available workers
  • Reusable: Workers are reused across multiple test files for efficiency
  • Fault tolerant: If a worker crashes, Playwright starts a new one
  • Configuring Workers

    JAVASCRIPT
    
    // playwright.config.js
    export default defineConfig({
      // Number of parallel workers
      workers: process.env.CI ? 2 : undefined, // 2 in CI, auto-detect locally
      
      // Alternative: specific number
      workers: 4, // Always use 4 workers
      
      // Alternative: disable parallelism
      workers: 1, // Run tests sequentially
    });
    

    Default behavior:

  • Locally: Uses number of CPU cores (e.g., 4 cores = 4 workers)
  • CI: Recommended to use fewer workers (1-2) for stability
  • What is Test Sharding?

    Sharding in Playwright means splitting your tests into smaller parts called "shards". Each shard is like a separate job that can run independently. The whole purpose is to divide your tests to speed up test runtime.

    graph TB subgraph "Test Sharding" TestSuite[๐Ÿ“š Complete Test Suite
    1000 Tests
    ⏱️ 60 min sequential] TestSuite --> Shard1[๐ŸŽฏ Shard 1/4
    Tests 1-250
    --shard=1/4] TestSuite --> Shard2[๐ŸŽฏ Shard 2/4
    Tests 251-500
    --shard=2/4] TestSuite --> Shard3[๐ŸŽฏ Shard 3/4
    Tests 501-750
    --shard=3/4] TestSuite --> Shard4[๐ŸŽฏ Shard 4/4
    Tests 751-1000
    --shard=4/4] Shard1 --> Machine1[๐Ÿ–ฅ️ Machine 1
    ⏱️ 15 minutes] Shard2 --> Machine2[๐Ÿ–ฅ️ Machine 2
    ⏱️ 15 minutes] Shard3 --> Machine3[๐Ÿ–ฅ️ Machine 3
    ⏱️ 15 minutes] Shard4 --> Machine4[๐Ÿ–ฅ️ Machine 4
    ⏱️ 15 minutes] Machine1 --> Result[๐Ÿš€ Total Time: 15 minutes
    vs 60 minutes sequential
    ⚡ 4x Faster!] Machine2 --> Result Machine3 --> Result Machine4 --> Result end style TestSuite fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px style Shard1 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Shard2 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Shard3 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Shard4 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Machine1 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px style Machine2 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px style Machine3 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px style Machine4 fill:#e1f5fe,stroke:#0277bd,stroke-width:2px style Result fill:#fff8e1,stroke:#f57f17,stroke-width:4px

    When you shard your tests, each shard can run on its own, utilizing the available CPU cores. This helps speed up the testing process by doing tasks simultaneously. In a CI pipeline, each shard can run as a separate job, making use of the hardware resources available in your CI pipeline, like CPU cores, to run tests faster.

    Key Differences:

  • Parallelism: Runs tests concurrently on the same machine using multiple CPU cores
  • Sharding: Distributes tests across multiple machines or CI jobs for horizontal scaling
  • ๐Ÿ†š How Playwright Sharding Differs from Selenium Grid

    Ever wondered how Playwright achieves distributed execution without the grid and node concepts that were foundational in Selenium? While we execute Selenium, Playwright, or any other tests through CI/CD systems, Playwright has simplified distributed execution by working with existing infrastructure rather than building its own.

    The Purpose of Distributed Execution

    Before diving into the differences, let's understand why distributed execution matters:

  • Reduced Test Time: Instead of running 1000 tests sequentially in 60 minutes, distribute them across 4 machines to complete in ~15 minutes
  • Better Resource Utilization: Leverage multiple machines' CPU and memory simultaneously
  • Faster Feedback: Get test results quickly to accelerate development cycles
  • Scalability: Handle growing test suites without proportionally increasing execution time
  • The Architectural Approaches

    The approach to distributed testing represents one of the fundamental differences between Playwright and Selenium ecosystems.

    Selenium Grid Architecture

    Selenium Grid: The Grid lets you distribute and run tests in parallel on multiple machines

    Selenium Grid follows a hub-and-node architecture:

  • Hub: Central registry that manages test requests and routes them to available nodes
  • Nodes: Remote machines that register with the hub and execute tests
  • Dynamic distribution: Tests are dispatched in real-time to available nodes
  • Real-time load balancing: The hub manages resource allocation automatically
  • graph TB subgraph "Selenium Grid" Hub[๐Ÿข Selenium Hub
    Central Coordinator] Node1[๐Ÿ’ป Node 1
    ๐ŸŒ Chrome Browser] Node2[๐Ÿ’ป Node 2
    ๐ŸฆŠ Firefox Browser] Node3[๐Ÿ’ป Node 3
    ๐ŸŒ Chrome Browser] Node4[๐Ÿ’ป Node 4
    ๐ŸŽ Safari Browser] Tests[๐Ÿ“‹ Test Suite
    100 Tests] Tests --> Hub Hub --> Node1 Hub --> Node2 Hub --> Node3 Hub --> Node4 Node1 --> Results1[๐Ÿ“Š Results] Node2 --> Results2[๐Ÿ“Š Results] Node3 --> Results3[๐Ÿ“Š Results] Node4 --> Results4[๐Ÿ“Š Results] end style Hub fill:#ffebee,stroke:#d32f2f,stroke-width:3px style Node1 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Node2 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Node3 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Node4 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Tests fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style Results1 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style Results2 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style Results3 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style Results4 fill:#fff3e0,stroke:#f57c00,stroke-width:2px

    Playwright's Sharding Philosophy

    Playwright takes a fundamentally different approach:

  • Pre-determined distribution: Tests are divided beforehand using the --shard=x/y parameter
  • No central hub: Each shard runs independently without a coordinating server
  • Simplicity-focused: Designed to work seamlessly with modern CI/CD systems
  • Deterministic execution: The same shard always gets the same tests
  • graph TB subgraph "Playwright Sharding" TestSuite[๐Ÿ“š Test Suite
    100 Tests] subgraph "CI/CD System" CIServer[⚙️ CI Server
    Job Dispatcher] Agent1[⚡ Agent 1
    Shard 1/4
    Tests 1-25] Agent2[⚡ Agent 2
    Shard 2/4
    Tests 26-50] Agent3[⚡ Agent 3
    Shard 3/4
    Tests 51-75] Agent4[⚡ Agent 4
    Shard 4/4
    Tests 76-100] end TestSuite --> CIServer CIServer --> Agent1 CIServer --> Agent2 CIServer --> Agent3 CIServer --> Agent4 Agent1 --> BlobReport1[๐Ÿ“„ Blob Report 1] Agent2 --> BlobReport2[๐Ÿ“„ Blob Report 2] Agent3 --> BlobReport3[๐Ÿ“„ Blob Report 3] Agent4 --> BlobReport4[๐Ÿ“„ Blob Report 4] BlobReport1 --> MergedReport[๐Ÿ“‹ Merged HTML Report] BlobReport2 --> MergedReport BlobReport3 --> MergedReport BlobReport4 --> MergedReport end style TestSuite fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style CIServer fill:#e3f2fd,stroke:#1976d2,stroke-width:3px style Agent1 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Agent2 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Agent3 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Agent4 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style BlobReport1 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style BlobReport2 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style BlobReport3 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style BlobReport4 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style MergedReport fill:#fce4ec,stroke:#c2185b,stroke-width:3px

    Parallel Test Execution: Playwright supports running tests concurrently across multiple browsers and contexts, making it faster and more efficient for large test suites unless like Selenium where we need to set up Selenium Grid to run the tests in parallel.

    How CI/CD Systems Handle Multi-Machine Execution

    The key insight is that CI/CD systems execute on multiple execution environments through agent/runner architecture where:

  • Each execution environment hosts a CI agent/runner process - This can be:
  • Physical machines with agent software (like Selenium Grid nodes)
  • Virtual machines or cloud instances with runners
  • Docker containers running agent processes
  • Kubernetes pods with containerized runners
  • The CI server dispatches jobs to available agents - When you trigger a pipeline, the CI server sends work to registered agents regardless of their hosting method
  • You use CI configuration to control distribution - Your YAML/configuration tells the CI system how to distribute the work across available execution environments
  • Playwright's sharding works within any distributed execution model - The --shard=x/y parameter runs on whichever execution environment the CI system assigns
  • Common Execution Models:

    With Physical Machines (Traditional - like Selenium Grid):

  • Multiple physical servers each running agent software
  • Tests execute on dedicated hardware
  • Similar to Selenium Grid's node architecture
  • With Containerized Execution (Modern CI/CD):

  • CI system spins up multiple Docker containers
  • Each container runs a shard independently
  • No physical machine separation needed
  • Examples: GitHub Actions runners, Azure DevOps hosted agents
  • Hybrid Approach:

  • Mix of physical machines and containers
  • Self-hosted runners on physical hardware + cloud containers
  • Best of both worlds for different test types
  • Think of it this way:

  • CI Server = The orchestrator (GitHub Actions, Azure DevOps, etc.)
  • Agent/Runner = The worker process (can run anywhere)
  • Execution Environment = Where tests actually run (physical machine, VM, container, pod)
  • Job = The specific shard command sent to an execution environment
  • The key difference from Selenium Grid is that Playwright doesn't require you to set up physical machines - it leverages whatever execution infrastructure your CI/CD system provides.

    graph TB subgraph "CI/CD Infrastructure" CIServer[๐Ÿข CI/CD Server
    GitHub Actions] end subgraph "Execution Environment" Agent1[⚡ Runner 1
    Container/VM] Agent2[⚡ Runner 2
    Container/VM] Agent3[⚡ Runner 3
    Container/VM] Agent4[⚡ Runner 4
    Container/VM] end subgraph "Playwright Jobs" Job1[๐ŸŽฏ Shard 1/4
    npx playwright test --shard=1/4] Job2[๐ŸŽฏ Shard 2/4
    npx playwright test --shard=2/4] Job3[๐ŸŽฏ Shard 3/4
    npx playwright test --shard=3/4] Job4[๐ŸŽฏ Shard 4/4
    npx playwright test --shard=4/4] end subgraph "Test Results" Artifact1[๐Ÿ“ฆ Test Artifacts 1] Artifact2[๐Ÿ“ฆ Test Artifacts 2] Artifact3[๐Ÿ“ฆ Test Artifacts 3] Artifact4[๐Ÿ“ฆ Test Artifacts 4] end CIServer --> Job1 CIServer --> Job2 CIServer --> Job3 CIServer --> Job4 Job1 --> Agent1 Job2 --> Agent2 Job3 --> Agent3 Job4 --> Agent4 Agent1 --> Artifact1 Agent2 --> Artifact2 Agent3 --> Artifact3 Agent4 --> Artifact4 style CIServer fill:#e3f2fd,stroke:#1976d2,stroke-width:3px style Agent1 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Agent2 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Agent3 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Agent4 fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px style Job1 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style Job2 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style Job3 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style Job4 fill:#fff3e0,stroke:#f57c00,stroke-width:2px style Artifact1 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style Artifact2 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style Artifact3 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style Artifact4 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px

    The CI/CD system handles the "grid/node" concept - Playwright just provides the sharding mechanism that works within whatever distributed execution system you choose.

    Playwright's message is essentially: "We made sharding simple and deterministic. Use it with your CI/CD system's parallel job features instead of building complex grid infrastructure."

    Key Architectural Differences

    Aspect Selenium Grid Playwright Sharding
    Infrastructure Hub + Nodes CI Server + Agents/Runners
    Setup Complexity High (requires grid setup) Low (uses existing CI infrastructure)
    Load Balancing Dynamic, real-time Pre-calculated, deterministic
    Failure Handling Hub manages retries CI/CD system handles failures
    Maintenance Requires grid maintenance No additional infrastructure
    Orchestration Selenium Hub controls distribution CI/CD system controls job distribution
    Scalability Add more nodes to grid Add more CI agents/runners

    Playwright's Official Message on Sharding Implementation

    To shard the test suite, pass --shard=x/y to the command line. For example, to split the suite into four shards, each running one fourth of the tests: npx playwright test --shard=1/4 npx playwright test --shard=2/4 npx playwright test --shard=3/4 npx playwright test --shard=4/4

    The Two-Level Granularity Approach

    Sharding can be done at two levels of granularity depending on whether you use the [property: TestProject.fullyParallel] option or not. This affects how the tests are balanced across the shards.

    With fullyParallel: true:

    Tests are split at the individual test level, leading to more balanced shard execution.

    Without fullyParallel:

    Playwright Test defaults to file-level granularity, meaning entire test files are assigned to shards. In this case, the number of tests per file can greatly influence shard distribution.

    Playwright's Recommended Configuration

    JAVASCRIPT
    
    // playwright.config.ts
    import { defineConfig } from '@playwright/test';
    
    export default defineConfig({
      // Enable for better shard distribution
      fullyParallel: true,
      
      // Optimize workers for CI
      workers: process.env.CI ? 1 : undefined,
      
      // Configure blob reporter for sharding
      reporter: process.env.CI ? 'blob' : 'html',
    });
    

    ๐Ÿ› ️ Implementing Sharding in CI/CD Systems

    Playwright's Official Support

    Playwright provides excellent documentation and examples for implementing sharding across various CI/CD platforms. The framework is designed to work seamlessly with:

  • GitHub Actions - Native matrix strategy support
  • Azure DevOps - Pipeline matrix and parallel job configurations
  • GitLab CI - Built-in parallel execution features
  • Jenkins - Pipeline parallel stages
  • CircleCI - Parallelism and matrix jobs
  • Docker - Container-based sharding
  • And many others - Any CI system with parallel job capabilities
  • Basic Sharding Implementation

    The core concept remains the same across all platforms - use the --shard=x/y parameter:

    BASH
    
    # Basic sharding command structure
    npx playwright test --shard=1/4
    npx playwright test --shard=2/4
    npx playwright test --shard=3/4
    npx playwright test --shard=4/4
    

    Generic CI Configuration Pattern

    Most CI/CD systems follow this pattern for implementing Playwright sharding:

    YAML
    
    # Generic CI configuration structure
    jobs:
      test:
        strategy:
          matrix:
            shard: [1, 2, 3, 4]  # or parallel: 4
        steps:
          - name: Setup
            run: npm ci && npx playwright install --with-deps
          - name: Run Tests
            run: npx playwright test --shard=${{ matrix.shard }}/4
          - name: Upload Reports
            run: # Upload blob reports as artifacts
            
      merge-reports:
        needs: test
        steps:
          - name: Download Reports
            run: # Download all shard reports
          - name: Merge Reports
            run: npx playwright merge-reports --reporter html ./reports
    

    For Detailed Implementation Examples

    For platform-specific implementations, configurations, and advanced setups, visit the official Playwright documentation:

    ๐Ÿ“– Playwright Test Sharding Documentation

    The official docs provide:

  • Step-by-step guides for each CI/CD platform
  • Complete working examples
  • Advanced configuration options
  • Report merging strategies
  • Troubleshooting guides
  • GitHub Actions Implementation

    Simple 4-Shard Setup

    YAML
    
    name: Playwright Tests
    on:
      push:
        branches: [ main ]
    
    jobs:
      test:
        runs-on: ubuntu-latest
        strategy:
          matrix:
            shard: [1, 2, 3, 4]
        steps:
          - uses: actions/checkout@v4
          - uses: actions/setup-node@v4
            with:
              node-version: 18
          - name: Install dependencies
            run: npm ci
          - name: Install Playwright
            run: npx playwright install --with-deps
          - name: Run tests
            run: npx playwright test --shard=${{ matrix.shard }}/4
          - name: Upload reports
            uses: actions/upload-artifact@v4
            if: always()
            with:
              name: report-${{ matrix.shard }}
              path: blob-report
    

    With Report Merging

    YAML
    
    name: Playwright Tests with Reports
    on:
      push:
        branches: [ main ]
    
    jobs:
      test:
        runs-on: ubuntu-latest
        strategy:
          matrix:
            shard: [1, 2, 3, 4]
        steps:
          - uses: actions/checkout@v4
          - uses: actions/setup-node@v4
            with:
              node-version: 18
          - name: Install dependencies
            run: npm ci
          - name: Install Playwright
            run: npx playwright install --with-deps
          - name: Run tests
            run: npx playwright test --shard=${{ matrix.shard }}/4
          - name: Upload reports
            uses: actions/upload-artifact@v4
            if: always()
            with:
              name: report-${{ matrix.shard }}
              path: blob-report
    
      merge-reports:
        if: always()
        needs: test
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: actions/setup-node@v4
            with:
              node-version: 18
          - name: Install dependencies
            run: npm ci
          - name: Download all reports
            uses: actions/download-artifact@v4
            with:
              path: all-reports
              pattern: report-*
              merge-multiple: true
          - name: Merge reports
            run: npx playwright merge-reports --reporter html ./all-reports
          - name: Upload final report
            uses: actions/upload-artifact@v4
            with:
              name: final-report
              path: playwright-report
    

    Docker Implementation

    Simple Dockerfile

    DOCKERFILE
    
    FROM mcr.microsoft.com/playwright:v1.54.0-noble
    
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    COPY . .
    
    CMD npx playwright test --shard=${SHARD_INDEX}/${SHARD_TOTAL}
    

    Running Docker Shards

    BASH
    
    # Run 4 shards manually
    docker run -e SHARD_INDEX=1 -e SHARD_TOTAL=4 my-playwright-tests
    docker run -e SHARD_INDEX=2 -e SHARD_TOTAL=4 my-playwright-tests
    docker run -e SHARD_INDEX=3 -e SHARD_TOTAL=4 my-playwright-tests
    docker run -e SHARD_INDEX=4 -e SHARD_TOTAL=4 my-playwright-tests
    

    Simple Docker Compose

    YAML
    
    version: '3.8'
    services:
      test-shard-1:
        build: .
        environment:
          - SHARD_INDEX=1
          - SHARD_TOTAL=4
    
      test-shard-2:
        build: .
        environment:
          - SHARD_INDEX=2
          - SHARD_TOTAL=4
    
      test-shard-3:
        build: .
        environment:
          - SHARD_INDEX=3
          - SHARD_TOTAL=4
    
      test-shard-4:
        build: .
        environment:
          - SHARD_INDEX=4
          - SHARD_TOTAL=4
    

    Run All Shards

    BASH
    
    # Start all shards
    docker-compose up
    
    # Or run in parallel
    docker-compose up --scale test-shard-1=1 --scale test-shard-2=1 --scale test-shard-3=1 --scale test-shard-4=1
    

    Azure DevOps Implementation

    Simple Azure Pipeline

    YAML
    
    trigger:
      - main
    
    jobs:
    - job: playwright_tests
      displayName: 'Run Playwright Tests'
      strategy:
        matrix:
          shard1:
            shardIndex: 1
          shard2:
            shardIndex: 2
          shard3:
            shardIndex: 3
          shard4:
            shardIndex: 4
      pool:
        vmImage: ubuntu-latest
      steps:
      - task: NodeTool@0
        inputs:
          versionSpec: '18'
      - script: npm ci
        displayName: 'Install dependencies'
      - script: npx playwright install --with-deps
        displayName: 'Install Playwright'
      - script: npx playwright test --shard=$(shardIndex)/4
        displayName: 'Run tests'
      - task: PublishPipelineArtifact@1
        condition: always()
        inputs:
          targetPath: 'blob-report'
          artifactName: 'report-$(shardIndex)'
    

    With Report Merging

    YAML
    
    trigger:
      - main
    
    jobs:
    # Test shards
    - job: test_shards
      displayName: 'Run Test Shards'
      strategy:
        matrix:
          shard1: { shardIndex: 1 }
          shard2: { shardIndex: 2 }
          shard3: { shardIndex: 3 }
          shard4: { shardIndex: 4 }
      pool:
        vmImage: ubuntu-latest
      steps:
      - task: NodeTool@0
        inputs:
          versionSpec: '18'
      - script: npm ci
        displayName: 'Install dependencies'
      - script: npx playwright install --with-deps
        displayName: 'Install Playwright'
      - script: npx playwright test --shard=$(shardIndex)/4
        displayName: 'Run tests'
      - task: PublishPipelineArtifact@1
        condition: always()
        inputs:
          targetPath: 'blob-report'
          artifactName: 'report-$(shardIndex)'
    
    # Merge reports
    - job: merge_reports
      displayName: 'Merge Reports'
      dependsOn: test_shards
      condition: always()
      pool:
        vmImage: ubuntu-latest
      steps:
      - task: NodeTool@0
        inputs:
          versionSpec: '18'
      - script: npm ci
        displayName: 'Install dependencies'
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: 'report-1'
          targetPath: 'all-reports'
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: 'report-2'
          targetPath: 'all-reports'
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: 'report-3'
          targetPath: 'all-reports'
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: 'report-4'
          targetPath: 'all-reports'
      - script: npx playwright merge-reports --reporter html ./all-reports
        displayName: 'Merge reports'
      - task: PublishPipelineArtifact@1
        inputs:
          targetPath: 'playwright-report'
          artifactName: 'final-report'
    

    Using Parallel Jobs (Simpler)

    YAML
    
    trigger:
      - main
    
    jobs:
    - job: playwright_tests
      displayName: 'Playwright Tests'
      strategy:
        parallel: 4  # Creates 4 parallel jobs automatically
      pool:
        vmImage: ubuntu-latest
      steps:
      - task: NodeTool@0
        inputs:
          versionSpec: '18'
      - script: npm ci
        displayName: 'Install dependencies'
      - script: npx playwright install --with-deps
        displayName: 'Install Playwright'
      - script: npx playwright test --shard=$(System.JobPositionInPhase)/4
        displayName: 'Run tests'
      - task: PublishPipelineArtifact@1
        condition: always()
        inputs:
          targetPath: 'blob-report'
          artifactName: 'report-$(System.JobPositionInPhase)'
    

    ✨ Best Practices and Configuration

    Playwright Configuration for Optimal Sharding

    JAVASCRIPT
    
    // playwright.config.js
    import { defineConfig } from '@playwright/test';
    
    export default defineConfig({
      // Essential for better test distribution across shards
      fullyParallel: true,
      
      // Optimize workers for CI environment
      workers: process.env.CI ? 1 : undefined,
      
      // Configure blob reporter for sharding and report merging
      reporter: process.env.CI ? 'blob' : 'html',
      
      // Retry failed tests in CI for stability
      retries: process.env.CI ? 2 : 0,
      
      // Optimize resource usage in distributed execution
      use: {
        trace: 'retain-on-failure',
        screenshot: 'only-on-failure',
        video: 'retain-on-failure',
      },
      
      projects: [
        {
          name: 'chromium',
          use: { browserName: 'chromium' },
        },
        // Add more projects as needed
      ],
    });
    

    Choosing the Right Number of Shards

    Simple Guidelines:

  • Small projects (< 50 tests): 2-3 shards
  • Medium projects (50-200 tests): 4-6 shards
  • Large projects (200+ tests): 6-10 shards
  • Formula approach:

    BASH
    
    # Measure your current test execution time
    time npx playwright test
    
    # Target: 5-10 minutes per shard
    # If total time is 40 minutes, use 4-8 shards
    # If total time is 20 minutes, use 2-4 shards
    

    Quick Setup Commands

    BASH
    
    # Run tests locally with sharding
    npx playwright test --shard=1/4
    npx playwright test --shard=2/4
    npx playwright test --shard=3/4
    npx playwright test --shard=4/4
    
    # Check test distribution
    npx playwright test --list --shard=1/4
    

    Common Issues and Simple Fixes

    Problem: Uneven shard execution times

    JAVASCRIPT
    
    // Add to playwright.config.js
    export default defineConfig({
      fullyParallel: true,  // This fixes most distribution issues
    });
    

    Problem: Reports not merging

    BASH
    
    # Make sure you have blob reporter configured
    # In CI: reporter: 'blob'
    # Then merge with:
    npx playwright merge-reports --reporter html ./all-reports
    

    Problem: Out of memory in CI

    JAVASCRIPT
    
    // Reduce resource usage
    export default defineConfig({
      workers: 1,  // Use only 1 worker per shard
      use: {
        video: 'retain-on-failure',  // Only record on failure
        screenshot: 'only-on-failure',
      },
    });
    

    Key Configuration Considerations

  • Enable fullyParallel: true - Ensures even test distribution across shards
  • Use workers: 1 in CI - Prevents resource conflicts when multiple shards run on same infrastructure
  • Configure blob reporter - Essential for merging reports from multiple shards
  • Set appropriate retries - Compensates for flaky tests in distributed execution
  • Optimize resource usage - Reduce memory and storage usage per test
  • Quick Verification Commands

    BASH
    
    # Test your sharding setup locally
    npx playwright test --list --shard=1/4  # See which tests go to shard 1
    npx playwright test --dry-run --shard=1/4  # Verify test distribution
    
    # Check if tests are properly distributed
    npx playwright test --list --shard=1/4 | wc -l
    npx playwright test --list --shard=2/4 | wc -l
    # Numbers should be roughly equal
    

    ๐ŸŽฏ Conclusion

    Playwright's approach to test sharding represents a paradigm shift from traditional grid-based architectures to a more modern, CI/CD-native solution. While Selenium Grid offers dynamic load balancing and real-time distribution, Playwright's deterministic sharding integrates seamlessly with existing CI/CD infrastructure without requiring additional distributed system management.

    ๐Ÿ’ญ "Playwright's message is essentially: 'We made sharding simple and deterministic. Use it with your CI/CD system's parallel job features instead of building complex grid infrastructure.'"

    Key Takeaways:

  • Simplicity First: Playwright prioritizes ease of implementation over complex infrastructure
  • CI/CD Integration: Designed to work naturally with modern pipeline systems
  • Deterministic Execution: Predictable test distribution aids in debugging and optimization
  • Modern Web Focus: Optimized for contemporary web applications and development practices
  • Now, if you run these shards in parallel on different jobs, your test suite completes four times faster.

    By implementing the strategies and configurations outlined in this guide, teams can achieve significant improvements in test execution speed while maintaining the reliability and comprehensiveness of their test suites. The key is to start simple, monitor performance, and iteratively optimize based on your specific testing requirements and infrastructure constraints.

    What's your experience with distributed testing? Have you tried Playwright sharding in your projects? Share your insights and challenges in the comments below!

    Ready to get started? Check out the official Playwright sharding documentation for detailed implementation guides.


    ๐Ÿ’ฌ Have questions about implementing sharding in your specific CI/CD setup? Drop a comment below or connect with me - I love discussing test automation strategies and helping teams optimize their testing workflows!

    No comments :

    Post a Comment