Try Serpent Free

How to fix Apex test failures and code coverage errors in Salesforce deployments

Production deployments require passing Apex tests and at least 75% code coverage, and Salesforce blocks the release until both are met.

Surfaces during: deployment to production or a full sandbox refresh

What it means

Salesforce requires that deployments to production run Apex tests and reach at least 75% average code coverage across all classes and triggers, with every trigger needing some coverage. A deployment fails, listing each failed test's assertion or exception, whenever a test throws an unhandled exception, an assertion fails, or the org's average coverage drops below that threshold.

This only gates production and full-sandbox deploys with RunLocalTests or RunAllTestsInOrg; deploys to Developer sandboxes or scratch orgs with NoTestRun skip the requirement entirely, which is exactly why coverage gaps go unnoticed until release day.

Diagnosis

Common causes

A test asserts against data changed by unrelated code
A newly deployed trigger or Flow changes a field the test asserts on, so the test's expected value no longer matches, even though the test itself wasn't touched.
New code shipped without tests to cover it
A class or trigger was added or expanded without a corresponding test method, pulling the org's average coverage below 75%.
Test depends on org-specific data or configuration
The test queries existing records, record types, or settings instead of creating its own data, so it passes in one org and fails in another where that data doesn't exist.

The fix

  1. Reproduce the failure locally first
    Run the full local test suite with coverage against your sandbox before touching the code, so you're debugging the real failure and not a stale deploy log.
    sf apex run test --test-level RunLocalTests --code-coverage --result-format human --wait 20
  2. Write tests for any new code before deploying
    Add test methods that exercise new classes and triggers so the org's average coverage clears 75% before the release.
  3. Make tests self-contained
    Rewrite tests to create their own test data with @TestSetup or Test.startTest() instead of relying on records that happen to exist in the target org.
In practice

How Serpent prevents this

Serpent's VS Code extension surfaces test results and coverage on the task itself, so a coverage gap or failing assertion is visible before a task is submitted, not discovered during a production deploy. See the Salesforce deployment error library.

Releases
Tasks
Orgs
v2.8.3 · Production
Components
AccountTrigger
OpportunityFlow
DashboardLWC
PermissionSet_A
EmailTemplate
0 of 5 ready
Serpent AI Review
Analysing…
No breaking changes
Test coverage: 94%
Dependencies mapped
Delta validated
Waiting for AI review…
✓ Deployed to Production · just now

Prevention

Gate merges on coverage, not just pass/fail
Fail CI on any pull request that drops org-wide coverage below 75%, not only on a hard test failure, so the gap never reaches a release.
Never assert on record counts without WHERE scoping
Scope every assertion query to the records the test itself created, so unrelated automation added later can't silently break the assertion.
Run RunLocalTests validation before every production release
Kick off a check-only deploy with RunLocalTests ahead of the real release so failures surface with time to fix, not during the deploy window.
Common questions

APEX TEST FAILURES, answered

Does 75% coverage guarantee a deployment will succeed?
No. Coverage is a minimum threshold, not a quality bar. Every test still has to actually pass; a suite can clear 75% coverage and still fail the deployment if even one test throws an unhandled exception or a failed assertion.
Does every individual class need 75% coverage?
No, the 75% threshold is an org-wide average. Individual classes can sit below it as long as the overall average clears the bar, though every trigger still needs at least some coverage.
Why did a test that never changed suddenly start failing?
Something else in the same transaction changed: a new trigger, Flow, or validation rule now touches data the test asserts on. Check what else deployed alongside the failing test.

Start free. No credit card, no install, no commitment.

Set up in under 15 minutes. No DevOps hire needed.

Curious about faster shipping before you dive in? Let's talk

Commitment free!