This post goes over how to shard Cypress specs on GitHub Actions:
Parallel
If you have a Cypress Cloud account, you can spin multiple containers running in parallel using strategy: matrix
:
# .github/workflows/cypress.yml
name: Parallel Cypress Tests
on: push
jobs:
test:
name: Cypress run
runs-on: ubuntu-latest
strategy:
# when one test fails, DO NOT cancel the other
# containers, because this will kill Cypress processes
# leaving Cypress Cloud hanging ...
# https://github.com/cypress-io/github-action/issues/48
fail-fast: false
matrix:
# run 3 copies of the current job in parallel
containers: [1, 2, 3]
steps:
- name: Checkout repository
uses: actions/checkout@v4
# because of "record" and "parallel" parameters
# these containers will load balance all found tests among themselves
- name: Cypress run
uses: cypress-io/github-action@v6
with:
record: true
parallel: true
group: 'Actions example'
env:
# pass the Cypress Cloud record key as an environment variable
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
# Recommended: pass the GitHub token lets this action correctly
# determine the unique run id necessary to re-run the checks
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
See the Cypress docs for more information on parallelization.
Shard
You can shard the Cypress specs with Bash using GitHub Actions:
# .github/workflows/cypress.yml
name: Shard Cypress Tests
on: push
jobs:
cypress:
runs-on: ubuntu-latest
strategy:
matrix:
# shard is zero-based since we're using the `split` command
shard: [0, 1, 2]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Split specs
id: specs
run: |
# find and save all spec paths to a file
SPECS=specs.txt
find cypress/e2e -type f -name '*.cy.*' > $SPECS
# count the total number of spec files
SPECS_COUNT=$(wc -l < $SPECS)
# calculate the number of lines to split (rounded up)
LINES=$(( ($SPECS_COUNT + 1) / ${{ strategy.job-total }} ))
# split the spec files
split -d -l $LINES $SPECS spec
# save the current shard of spec files to an output parameter
echo "SPECS<<EOF" >> $GITHUB_OUTPUT
cat spec0${{ matrix.shard }} >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Cypress run
uses: cypress-io/github-action@v6
with:
browser: chrome
spec: |
# pass specs from the previous step
${{ steps.specs.outputs.SPECS }}
You can see that the Cypress specs were split into 3 shards and passed into the GitHub Action via an output parameter. Alternatively, you can store the specs in an environment variable.
See example remarkablemark/cypress-cucumber-steps#979.