14.1 Testing Framework & Coverage Requirements
Key Takeaways
- Salesforce requires automated Apex tests for deployment: overall Apex code coverage in the destination org must be at least 75%
- Each Apex trigger must have some test coverage; classes should be covered by meaningful tests that assert outcomes
- Mark test classes and methods with @IsTest (or @isTest); test code does not count toward org coverage and cannot be called from production Apex
- Coverage is necessary but not sufficient—tests must assert business behavior, not merely execute lines
- Sandbox and scratch orgs are for development and validation; production deployments fail if coverage or test failures block the deploy
14.1 Testing Framework & Coverage Requirements
Quick Answer: Salesforce will not deploy Apex to production (or many sandboxes under typical CI/CD gates) unless unit tests pass and the destination org’s overall Apex code coverage is at least 75%. Triggers must receive coverage. Use
@IsTestclasses to exercise production code with DML and assertions. Coverage is required; correct assertions prove the logic works.
Testing, Debugging, and Deployment is roughly 20% of Platform Developer I. The exam expects you to know why tests exist, what the coverage numbers mean, how test classes are structured, and why “green coverage” without assertions is not real quality.
Why Apex Tests Are Required
Apex runs multi-tenant on shared infrastructure. A broken trigger can block every user saving records on that object. Automated tests give the platform a safety net:
- Regression protection when metadata or dependent code changes
- Governor-limit rehearsal under bulk DML in a controlled context
- Deployment gate so untested or broken code cannot casually reach production
- Documentation of expected behavior through assert messages and test names
Unlike optional unit tests in some ecosystems, Salesforce enforces a coverage floor for deployment of Apex. That policy is exam-critical and operationally real.
The 75% Coverage Rule
When you deploy Apex (classes, triggers, and related metadata) into an org, Salesforce evaluates overall code coverage of Apex in the target org after the deploy, not merely “did my new file get 75%.” Key facts:
| Rule | What it means |
|---|---|
| ≥ 75% overall | Across all Apex (classes + triggers) that count toward coverage in the destination org |
| Triggers need coverage | Each trigger should be covered by tests; uncovered triggers block deploys |
| Tests must succeed | Failed tests fail the deployment (or validation) |
| Test code is free | Code inside @IsTest classes does not count toward the 75% denominator |
Coverage is calculated from lines executed during test runs included in the deployment or validation, depending on test level (RunLocalTests, RunSpecifiedTests, etc.—covered in 14.4). For learning and the exam, remember the headline: 75% org-wide, triggers covered, tests must pass.
What Coverage Does Not Mean
- Hitting a line once does not prove edge cases work.
- Covering a method without
System.assert/Assertmay still leave bugs. - 100% coverage on a class can still ship wrong business rules if assertions are weak or missing.
Coverage is necessary but not sufficient. Good teams treat 75% as a minimum gate, not a quality target.
Sandbox, Scratch, and Production Contexts
| Environment | Typical role |
|---|---|
| Scratch / Developer sandbox | Author Apex and tests; iterate quickly |
| Partial / Full sandbox | Integration-style validation closer to prod data shape |
| Production | Strictest operational bar; deploy validation uses tests + coverage |
You can run tests anytime in sandboxes via Developer Console, VS Code, Setup, or CLI. Production deployment (and many pipeline “check-only” validations against production) re-runs the coverage math. If overall coverage would drop below 75%, or required tests fail, the deploy is rejected.
Development practice: keep coverage comfortably above 75% so a small new class does not drag the org under the floor. Orgs that live at 75.1% are fragile.
@IsTest Classes and Methods
Test Apex lives in dedicated classes annotated with @IsTest (case-insensitive @isTest also works). Common pattern:
@IsTest
private class AccountServiceTest {
@IsTest
static void applyDefaultIndustry_setsTechnology() {
Account a = new Account(Name = 'Acme');
Test.startTest();
AccountService.applyDefaultIndustry(a);
Test.stopTest();
System.assertEquals('Technology', a.Industry,
'Default industry should be Technology when blank');
}
}
Rules You Will See on the Exam
@IsTeston the class marks the class as test-only: it does not deploy as runnable production logic and is excluded from coverage percentages.- Test methods are typically
static void, annotated@IsTest(or the oldertestMethodkeyword—prefer@IsTest). - Access: test classes are often
private; they can still callpublic/@TestVisiblemembers of production classes. - No production call into tests: production Apex cannot invoke test methods.
- Governor limits still apply inside tests (with
Test.startTest/stopTestgiving a fresh limit window—section 14.2).
@TestVisible on private production members lets tests reach internals without widening production API surface—use sparingly; prefer testing through public behavior.
Assert Behavior, Not Just Lines
A test that only inserts a record to “cover” a trigger may raise coverage while leaving bugs undetected:
// Weak: covers lines, proves little
@IsTest
static void coverTrigger() {
insert new Account(Name = 'x');
}
// Strong: covers lines and proves outcome
@IsTest
static void triggerSetsStatusOnInsert() {
Account a = new Account(Name = 'Acme');
insert a;
a = [SELECT Status__c FROM Account WHERE Id = :a.Id];
System.assertEquals('New', a.Status__c,
'Account trigger should stamp Status__c = New on insert');
}
Assert on state after the act: field values, related child counts, error messages via Database.SaveResult, and that invalid paths throw or fail as designed.
What Counts Toward Coverage
Executed executable lines in non-test Apex count. Comments, blank lines, and many pure declarations contribute little or nothing. Exception paths and branches need dedicated tests if you care about covering them. For the exam, you do not need bytecode-level detail—know that tests execute production code, and only that execution raises the percentage.
Deployment Mental Model
- Developer writes production Apex + tests in a sandbox/scratch org.
- Local or pipeline run executes tests; failures stop the merge.
- Deploy/validate to next environment with a test level (often RunLocalTests).
- Salesforce ensures tests pass and resulting org coverage ≥ 75%, with triggers covered.
- Only then does production Apex change go live.
If someone uses Execute Anonymous to “try” logic, that is not a unit test and contributes no coverage (section 14.4).
Exam Checklist
- 75% overall Apex coverage is the standard deployment floor for the target org.
- Triggers must be covered; uncovered triggers block deploys.
@IsTestmarks test classes/methods; test code is excluded from coverage math.- Passing tests + coverage are both required; coverage without assertions is incomplete quality.
- Prefer sandboxes for development; production is protected by the same automated gates.
Master this framework first—later sections show how to write tests, isolate data, and run them correctly.
What is the standard minimum overall Apex code coverage Salesforce requires for deployment into the target org?
Why is high line coverage alone not enough to prove Apex quality?
Which statement about @IsTest Apex is correct?