DEV Community

Renuka Singh
Renuka Singh

Posted on

Salesforce Apex Testing: How to Write Tests That Catch Real Bugs

Writing Apex tests is not just about achieving code coverage. Good tests help developers identify bugs, protect existing functionality, and make Salesforce deployments more reliable.

A test can achieve high coverage and still miss important problems if it checks only the simplest scenario. The goal should be to test how the code behaves under different conditions.

  1. Test Business Behavior, Not Just Execution

Suppose an Apex class updates an Opportunity when certain conditions are met.

A weak test might only verify that the method executes without throwing an exception. A stronger test checks whether the Opportunity was updated correctly.

@IsTest
private class OpportunityServiceTest {
@IsTest
static void updatesOpportunityStage() {
Account account = new Account(Name = 'Test Account');
insert account;

    Opportunity opp = new Opportunity(
        Name = 'Test Opportunity',
        AccountId = account.Id,
        StageName = 'Prospecting',
        CloseDate = Date.today().addDays(30)
    );
    insert opp;

    Test.startTest();
    OpportunityService.updateStage(opp.Id);
    Test.stopTest();

    Opportunity updatedOpp = [
        SELECT StageName
        FROM Opportunity
        WHERE Id = :opp.Id
    ];

    System.assertEquals(
        'Qualification',
        updatedOpp.StageName,
        'The Opportunity stage should be updated.'
    );
}
Enter fullscreen mode Exit fullscreen mode

}

This example assumes that OpportunityService.updateStage() is implemented to change the stage to Qualification. The test verifies the expected business result rather than merely executing the method.

  1. Create Your Own Test Data

Tests should generally create the records they need instead of depending on existing Salesforce data.

This makes tests more predictable across development, testing, and deployment environments.

Use @TestSetup when multiple test methods need the same foundational records. For example, a test class may create an Account once and reuse that setup across its test methods.

Keep test data focused on the scenario being tested.

  1. Test Positive and Negative Scenarios

Real applications must handle more than successful requests.

Consider testing:

Valid record updates

Missing or invalid input

Records that do not meet business conditions

Users with different access levels where relevant

Expected exceptions or validation failures

For example, if a service should reject an Opportunity without a required business condition, write a test that verifies the rejection behavior.

Negative tests often reveal problems that happy-path tests miss.

  1. Test Bulk Operations

Salesforce automation may process multiple records in one transaction. Code that works for one record may fail when handling a larger collection.

When testing triggers or bulk-processing services, insert or update multiple records in a single operation.

Then verify that every expected record was processed correctly.

This helps expose problems such as SOQL queries inside loops, assumptions about a single record, and inefficient processing.

  1. Use Test.startTest() and Test.stopTest() Correctly

These methods create a fresh set of governor limits for the test operation and help execute asynchronous work where applicable.

Place them around the operation you want to test, rather than wrapping the entire test method without a clear reason.

For asynchronous Apex, also verify the actual outcome of the queued work after the test execution completes.

  1. Avoid Tests That Depend on Implementation Details

Tests become fragile when they depend on internal details that are not part of the expected behavior.

Prefer checking observable results, such as updated field values, created records, and expected error handling.

When a business requirement changes, a well-designed test should make it clear whether the behavior is still correct.

  1. Remember That Coverage Is Only One Measure

Salesforce requires Apex tests to meet platform deployment coverage requirements. However, reaching the required percentage does not guarantee code quality.

A useful test suite should also provide meaningful assertions, cover important edge cases, and remain maintainable as the application grows.

Review failures carefully and avoid adding assertions that simply repeat what the code already does without verifying the intended result.

Final Thoughts

Reliable Apex testing starts with clear business expectations. Create controlled test data, cover positive and negative scenarios, test bulk behavior, and verify actual results.

When tests focus on behavior rather than coverage alone, they become a practical tool for safer Salesforce development and easier maintenance.

Top comments (0)