jobs:
test:
runs-on: ubuntu-latest
strategy: { matrix: { shard: [1, 2, 3] } }
services:
postgres:
image: postgres:16
env: { POSTGRES_PASSWORD: test }
ports: ['5432:5432']
options: --health-cmd pg_isready --health-interval 5s
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx jest --ci --shard=${{ matrix.shard }}/3
Run fast checks first and slow suites later, use real dependencies, and run tests in parallel with an isolated database for each worker.
Order for fast feedback:
- lint and type-check
- unit tests
- integration and e2e tests
Use npm ci and cache dependencies.
Real dependencies. Run Postgres, Redis and similar as CI service containers or with Testcontainers. Pin them to the versions you use in production. Add health checks, so tests don't start before Postgres is ready. Apply migrations as part of setup.
Parallel runs at two levels:
- Jest workers inside one job. Size
--maxWorkersfor the CI machine. - Sharding across jobs with
--shard=i/n. Jest and Vitest both support it.
Each worker or shard needs its own database or schema, so tests don't change each other's data.
Reliability and reports:
- Run with
--ci. - Publish JUnit and coverage reports.
- Keep logs on failure.
- Set job timeouts.
- Track flaky tests and quarantine them with an owner. Don't add retries to everything.
- Run fast checks first and slower suites after.
- Use real Postgres and Redis as CI services or Testcontainers, with health checks.
- Use workers inside a job and shards across jobs.
- Give each worker or shard its own isolated database.
- Publish reports, keep logs, set timeouts and track flaky tests.
Read more
- Jest CLI options (https://jestjs.io/docs/cli)jestjs.io
- Testcontainers (https://testcontainers.com/)testcontainers.com