Apex Test Classes and Code Coverage: A Beginner Guide for PD1 (2026)

Header image: Apex test classes and code coverage, with a deploy checklist card showing 75% minimum coverage, some coverage for every trigger and all tests passing.

Hey friends,

To deploy Apex to production, at least 75% of your Apex code must be covered by tests, every trigger needs some coverage, and all tests must pass. But coverage only proves lines ran. A good test creates its own data, runs the code once, and asserts the result, including the bulk case and the failure case.

Testing is 20% of the Platform Developer I exam, and the guide asks you to write tests for triggers, controllers, classes and flows "using various sources of test data". The facts here come from Trailhead's Apex Testing module.

Table of Apex testing rules: 75% coverage and passing tests to deploy, some coverage on every trigger, test data rolled back, org data hidden unless SeeAllData is true, test utility classes excluded from code size.

The rules the exam likes to test.

What a test class looks like

A test class is annotated @IsTest. Declare it private if it's only for unit tests; public test classes are usually test data factories. Each test method is also annotated @IsTest, and its access modifier doesn't matter.

TemperatureConverterTest.apex
1@IsTest
2private class TemperatureConverterTest {
3    @IsTest static void testBoilingPoint() {
4        Decimal c = TemperatureConverter.FahrenheitToCelsius(212);
5        Assert.areEqual(100, c, 'Boiling point should be 100');
6    }
7}

Assert.areEqual takes the expected value first, then the actual value, and an optional message that shows up when it fails.

The pattern: arrange, act, assert

The arrange, act, assert pattern for Apex test methods: create data with a test data factory, run the code between Test.startTest and Test.stopTest, then assert the result.

Three steps in every test method.

Arrange with a test data factory. Trailhead's test data unit builds a TestDataFactory class with a method like createAccountsWithOpps(numAccts, numOppsPerAcct). Every test calls it instead of copying setup code. Bonus: test utility classes don't count toward your org's code size limit.

Act between Test.startTest() and Test.stopTest(). Trailhead's trigger tests put the one operation being tested between the two calls.

Assert the outcome. Did the record save? Was the error the right one? A test with no asserts can give you 100% coverage and catch nothing.

Test data: why tests shouldn't touch real records

  • Records created in a test aren't committed. They're rolled back when the test finishes.
  • There's no separate test database, so unique fields can still collide with existing records.
  • Tests can't see existing org data unless you use @IsTest(SeeAllData=true), and Trailhead calls that not a best practice. Tests that depend on org data break when someone changes the data.

Cert Lab by Nick Frates

Practice the Testing, Debugging and Deployment section

The Platform Developer Cert Lab covers testing, the Salesforce CLI, debugging and deployment, with practice questions that explain every option.

Start the PD1 Cert Lab, $9.99 →

What to test (beyond the happy path)

Trailhead's temperature example tests normal values, then points out what's missing: boundary values and invalid inputs. Passing null into that method throws a System.NullPointerException, and only a test that tries it will find out.

  1. The positive case: it does what it should with good data.
  2. The negative case: the trigger blocks what it should block. Trailhead's account deletion test checks that the delete fails with the right error.
  3. The bulk case: the same scenario with many records. This is where non-bulkified triggers fail.
  4. Boundaries and nulls: the edges of what the method accepts.

If your trigger isn't bulkified, the bulk test will tell you. Read my Apex trigger best practices first, then write the bulk test.

Checking coverage

After a run, coverage shows in the Developer Console's Tests tab. Rerun tests whenever the code changes. Trailhead notes a known Developer Console issue: running only a subset of tests may not update coverage correctly, so use Test, Run All.

Practice question. A deployment fails even though org-wide coverage is 82%. What's the most likely cause?

  • A. Coverage must be 90%
  • B. A trigger in the deployment has no test coverage, or a test is failing
  • C. Test classes count against coverage
  • D. Tests used a test data factory

Answer: B. 75% is the minimum, every trigger needs some coverage, and all tests must pass. A factory is the recommended approach, not a problem.

Keep studying

Cert Lab by Nick Frates

Get the Platform Developer Cert Lab

Lessons, practice questions and flashcards for every PD1 exam section.

Start the PD1 Cert Lab, $9.99 →

Hope this helps!

Best,

Nick

Keep reading

See all posts →

Salesforce Saturdays

Join 1,032 Salesforce pros getting one 10-minute tip on Salesforce tech or career growth every Saturday.