Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
All errors
Deployment

Average test coverage across all Apex Classes and Triggers is XX%, at least 75% required

A production deploy of Apex requires at least 75% line coverage *org-wide*, and 100% on triggers (including triggers that aren't part of your deploy). The error doesn't always tell you which class dragged the average down — you have to compute it.

Also seen asAverage test coverage·75% required·code coverage below 75·Code coverage requirement

Salesforce requires production deploys of Apex to keep the org's average test coverage at or above 75%. If your deploy adds 100 lines of uncovered code, the org's running average drops, and the deploy is rejected.

What "75%" actually measures

The platform calculates: total covered lines across all Apex classes and triggers ÷ total lines across all Apex classes and triggers. Multiply by 100. The deploy compares the predicted post-deploy figure against 75%.

Two consequences:

  1. The figure is org-wide. Your new class with 90% coverage can still tank the deploy if it adds enough lines to drop the average.
  2. Triggers must be at least 1% covered individually, otherwise the deploy fails on the trigger regardless of overall coverage.

How to find the offender

The deploy log usually names the lowest classes:

The following classes had test coverage below 75%:
  - DataMigrationOneoff: 0%
  - LegacyHelper: 32%

If it doesn't, query the platform:

SELECT ApexClassorTrigger.Name, NumLinesCovered, NumLinesUncovered
FROM ApexCodeCoverageAggregate
WHERE NumLinesCovered + NumLinesUncovered > 0
ORDER BY NumLinesCovered / (NumLinesCovered + NumLinesUncovered) ASC

(Run this in the Setup → Developer Console → Query Editor with the Tooling API checkbox on.)

The bottom rows are the classes pulling the average down. Add tests there, not at the new code's level.

Fix the right thing

There are three ways to bring coverage up:

  1. Cover the actual logic. The honest fix. Write tests that exercise the uncovered branches.
  2. Delete genuinely dead code. If DataMigrationOneoff ran in 2019 and never again, delete it. Lines that don't exist don't need coverage.
  3. Mark code as @TestVisible / @TestSetup-only. Sometimes legitimate config code can't be exercised at deploy time but can be by a test that injects the right state.

What you should not do: write Test.startTest(); MyClass.someMethod(...); Test.stopTest(); with no assertions. The platform counts the lines as covered, but the test proves nothing. Reviewers and future-you will hate this.

A common shortcut that doesn't help

Adding @SuppressWarnings('Coverage') does nothing to the platform — it's a Salesforce CLI/scanner annotation only. The platform still counts the lines.

The 1% trigger rule

A trigger with zero covered lines blocks production deploys regardless of org coverage. Even one assertion that fires the trigger and asserts it ran is enough to satisfy the rule. So a one-line Trigger.isExecuting test passes the gate; whether it does anything useful is up to you.

Quick deploys & coverage caching

A quick deploy uses cached coverage results from a recent validation. If you ran a validation deploy with RunSpecifiedTests covering the new code, you can quick-deploy that same payload and skip the full test run. This is how big orgs deploy to prod in 5 minutes instead of 90.

Related dictionary terms