
Andrew Hanna

Andrew Hanna

A Salesforce test automation pipeline runs your Apex and Lightning Web Component tests automatically on every commit, before code reaches production. A working setup connects a git repository to a CI runner, spins up a scratch org or sandbox, deploys the metadata, runs the tests, and fails the build if coverage drops below the 75 percent Salesforce requires. This guide walks the whole pipeline, from first test level to the traps that slow teams down.
Continuous integration (CI) is the practice of validating every change as it lands, instead of at a release gate. For Salesforce, that means a pipeline that runs your automated tests on each push or pull request and blocks the merge if anything fails. The goal is shift-left testing: catch a broken trigger or a failing assertion in minutes on a branch, not in a release-night deploy to production.
Salesforce enforces a hard rule that makes this non-negotiable: before you can deploy Apex to production, your tests must pass and you must have at least 75 percent code coverage. CI is how you keep that green continuously instead of scrambling at deploy time.
A useful Salesforce suite is layered. Aim to cover, fastest first:
@salesforce/sfdx-lwc-jest. These are fast and run without an org.
Run Apex and Jest on every commit because they are fast, and reserve slower UI end-to-end checks for a nightly stage. Our guide on what to run on every pull request and what to run nightly breaks that split down.
The moving parts are the same whether you use GitHub Actions, GitLab CI, or Jenkins. A minimal pipeline does this on each pull request:
sf project deploy start.sf apex run test --test-level RunLocalTests --code-coverage --result-format
human, and run npm run test:unit for LWC Jest.
Salesforce publishes an official walkthrough of Salesforce DX with GitHub Actions that maps cleanly onto these steps.
The test level controls how much runs and how long the build takes:
RunLocalTests runs every test in the org except those from installed
managed packages, and is the safe default for a validation pipeline.
RunSpecifiedTests runs only named classes, useful for fast branch
feedback but risky as a production gate because it can miss coverage.
RunRelevantTests level shipped in beta in the Spring '26
release to shorten deploys by running only the tests affected by a change; treat it
as beta until you have validated it against your suite.
For the merge-blocking build, prefer RunLocalTests so coverage is real.
Use specified or relevant tests only for quick, non-gating feedback earlier in the
branch.
Three mistakes account for most stalled pipelines:
Chasing the 75 percent number instead of real assertions. Coverage without assertions passes the gate and still ships bugs.
The other two are flaky test data and a suite that grows too slow to run on every
commit. Fix the first by creating test data inside each test with a factory pattern
and @testSetup, never relying on org data. Fix the second by splitting
fast unit tests from slow end-to-end tests, so feedback stays under a few minutes
where it matters most. Tooling from the Salesforce DevOps category, including Copado,
Gearset, Salto, AutoRABIT, Flosum, and Blue Canvas, can wrap these steps in a managed
pipeline if you would rather not hand-build the YAML.
For more Salesforce DevOps how-to guides, see our resources library.
What code coverage does Salesforce require to deploy?
At least 75 percent org-wide Apex coverage, and every test must pass. CI keeps this continuously green rather than discovering a shortfall at deploy time.
Do I need scratch orgs for Salesforce CI?
No, but they help. Scratch orgs give each build a clean, disposable environment. A dedicated CI sandbox works too if source tracking and reset are managed carefully.
How do I test Lightning Web Components in CI?
Use the Jest-based @salesforce/sfdx-lwc-jest runner. It runs component
tests locally without an org, so it is fast enough to run on every commit.
Which CI tool is best for Salesforce?
GitHub Actions, GitLab CI, and Jenkins all work well with the Salesforce CLI. The runner matters less than a clean pipeline: authenticate, deploy, run tests, gate, clean up.
Commitment free!