Stop 17 · CI/CD & DeploymentTopics · 4/9

Automated Testing in Pipelines

Part of the Backend Developer Roadmap

In short

A test you have to remember to run is a test you'll forget to run. Put tests in the pipeline and broken code can't reach main, even on a Friday evening.

Running your test suite automatically as part of CI, so broken code is caught before it ever reaches production — and often blocking merges/deploys if tests fail.

The purple blob feeds answer sheets into a machine that stamps green ticks and one red cross.

Think of it like this

The OMR checking machine

Board exams don't trust one tired teacher with lakhs of answer sheets. An OMR machine checks every sheet the same way, in seconds, with no mood swings. Pipeline tests are your OMR machine: same checks, every push, no favourites.

Watch it happen

Fail fast, cheapest checks first

Lint
Unit
Integration
E2E
Merge

1/5ESLint and tsc run first. They take seconds and catch typos before slower tests waste time.

The big ideas

What you need to know

The test pyramid

Many fast unit tests, fewer integration tests, a handful of end-to-end tests. Speed keeps people from skipping them.

Fast feedback wins

Run cheap checks first and stop at the first failure. A pipeline that takes 40 minutes gets ignored.

Real dependencies in CI

Service containers give each run a fresh Postgres or Redis, so tests never fight over a shared test database.

Make the check required

Turn on branch protection so the test job must pass before merging. Optional checks get skipped.

See it in code

Walk through the code

yaml
1jobs:2  test:3    runs-on: ubuntu-latest4    services:5      postgres:6        image: postgres:177        env:8          POSTGRES_PASSWORD: test9        ports: ["5432:5432"]10        options: --health-cmd pg_isready --health-interval 5s11    env:12      DATABASE_URL: postgres://postgres:test@localhost:5432/postgres13    steps:14      - uses: actions/checkout@v415      - run: npm ci && npm run lint && npm test

1/4Start a Postgres 17 container next to the job, reachable on localhost:5432.

Every run gets its own empty Postgres. When the job ends, the database is thrown away, so tests can't leave a mess for the next run.

Save yourself the pain

Common mistakes

Oops

Treating flaky tests with 'just re-run it'.

Do this instead

A flaky test trains everyone to ignore red. Fix it, or quarantine it with a ticket, the same day.

Oops

Running integration tests against one shared, long-lived staging database.

Do this instead

Tests then fail because of someone else's data. Give every pipeline run its own fresh database container.

Your mission

Make tests a gate

~30 min

Quick check

Your pipeline has lint (10 s), unit tests (1 min) and E2E tests (8 min). What order makes most sense?

Go deeper

  1. 1Configure your CI pipeline to fail the build if any test fails.
  2. 2Add a required status check so pull requests can't merge with failing tests.
  3. 3Include linting and type-checking alongside tests in the same pipeline.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge