# Writing and running Apex and Flow tests

*Platform Developer Study Guide · Testing, Debugging, and Deployment · Last updated October 15, 2026 · https://www.certifyforce.com/study-guide/platform-developer/testing-debugging-and-deployment/writing-and-running-apex-and-flow-tests*

How to structure @IsTest classes, pick a source of test data (@TestSetup, a data factory, Test.loadData, SeeAllData), isolate limits and async work with Test.startTest/stopTest, mock callouts, test triggers and controllers, meet the 75% coverage rule, and test flows with Test Mode or the debugger.

- Certification: Salesforce Platform Developer
- Exam section: Testing, Debugging, and Deployment
- Study guide: https://www.certifyforce.com/study-guide/platform-developer

**Official exam objective:**

> Write and execute tests for triggers, controllers, classes, and flows using various sources of test data.

## What the exam expects

- Structure test classes and methods for classes, triggers and Visualforce controllers.
- Choose a source of test data (records built in the test, `@TestSetup`, a test data factory, `Test.loadData`, or `SeeAllData=true`) and explain data isolation.
- Use `Test.startTest()`/`Test.stopTest()` to isolate governor limits and force asynchronous work (future, Queueable, batch) to finish before assertions.
- Replace callouts and dependencies with `HttpCalloutMock` or the Stub API, test as other users with `System.runAs()`, and prove bulk and negative paths with assertions.
- State the 75% coverage rule and what counts toward it; test flows with Test Mode or the Flow Builder debugger.

Key terms: **test class** (a class annotated `@IsTest` that holds test methods); **data isolation** (tests see only records they create, by default); **test setup method** (`@TestSetup`, builds shared records once per class); **mock** (a test-only stand-in that returns a canned response); **code coverage** (executable lines run by tests divided by all executable lines).

## Key facts

| Fact | Detail | Source |
|---|---|---|
| Default data access | Only records the test creates, plus setup objects such as User, Profile, RecordType | [Isolation of Test Data](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_data_access.htm) |
| Class-level `SeeAllData=true` | Method-level `SeeAllData=false` is ignored; records are still rolled back | [Using the isTest(SeeAllData=True) Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_seealldata_using.htm) |
| `startTest`/`stopTest` | Once each per test method; new limits between; async runs at `stopTest` | [Test Class](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_test.htm) |
| Batch Apex in a test | Only one execution of `execute`; limit records with the scope parameter | [Using Batch Apex](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm) |
| Register a callout mock | `Test.setMock(HttpCalloutMock.class, new MyMock())` before the callout | [Testing HTTP Callouts](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_http_testing_httpcalloutmock.htm) |
| Stub API can't mock | Static (including future) and private methods, properties, triggers | [Build a Mocking Framework with the Stub API](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_stub_api.htm) |
| `System.runAs()` | Enforces the user's sharing and permissions; test methods only | [Using the runAs Method](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_tools_runas.htm) |
| Deployment coverage | At least 75% of Apex, all tests pass, every trigger has some coverage | [Testing Best Practices](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_best_practices.htm) |
| Excluded from coverage | Test classes, comments, blank lines, lone `System.debug()` lines | [Testing and Code Coverage](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_code_coverage_intro.htm) |
| Flow Test Mode | Autolaunched and record-triggered flows; other types use the debugger | [Testing Your Flow Before Activation](https://help.salesforce.com/s/articleView?id=sf.flow_test.htm&type=5) |

## Check yourself

- Why does a query for records you can see in the sandbox return zero rows inside a test?
- When does a future method called in a test actually run?
- Why keep test data builders in an `@IsTest` utility class instead of a plain public class?
- Which flow types use Test Mode rather than the Flow Builder debugger?
- What minimum coverage must Apex have before it can be deployed to production?

## Sources

- [Testing Apex](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing.htm)
- [What Are Apex Unit Tests?](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_unit_tests.htm)
- [Isolation of Test Data from Organization Data in Unit Tests](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_data_access.htm)
- [Using the isTest(SeeAllData=True) Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_seealldata_using.htm)
- [Using Test Setup Methods](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_testsetup_using.htm)
- [Loading Test Data](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_load_data.htm)
- [Test Class](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_test.htm)
- [Testing and Code Coverage](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_code_coverage_intro.htm)
- [Testing Best Practices](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_best_practices.htm)
- [Testing HTTP Callouts by Implementing the HttpCalloutMock Interface](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_http_testing_httpcalloutmock.htm)
- [Build a Mocking Framework with the Stub API](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_stub_api.htm)
- [Using the runAs Method](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_tools_runas.htm)
- [Testing Example](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_example.htm)
- [Using Batch Apex](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm)
- [Assert Class](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_Assert.htm)
- [Limits Class](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_limits.htm)
- [Test a Custom Controller](https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_controller_error_handling.htm)
- [Testing Your Flow Before Activation](https://help.salesforce.com/s/articleView?id=sf.flow_test.htm&type=5)
- [Create Test Data for Apex Tests (Trailhead)](https://trailhead.salesforce.com/content/learn/modules/apex_testing/apex_testing_data)
- [Test Apex Triggers (Trailhead)](https://trailhead.salesforce.com/content/learn/modules/apex_testing/apex_testing_triggers)

## About the full unit

The "Core concepts", "Exam traps" and "Worked scenario" sections of this unit, its 25 linked practice questions, and unlimited timed mock exams are included with the Platform Developer pack (USD $19): https://www.certifyforce.com/practice-exams
