Quick Reference Guide

Salesforce Apex, SOQL & Test Class Best Practices

Salesforce
Intermediate Level

Salesforce Apex, SOQL & Test Class Best Practices

32 Downloads
16 Views
1 Pages
Jul 30, 2026

About This Cheat Sheet

Hey there! Welcome to your complete guide to Apex, SOQL & Test Class Best Practices for Salesforce development. I've put together everything you need to know โ€” from Apex Best Practices (Bulkification, Avoid SOQL in Loops, Collections, Governor Limits, Exception Handling, Separation of Concerns) to SOQL Best Practices (Selective Queries, Indexing, Bind Variables, Security Enforcement) and Test Class Best Practices (@isTest, Test.startTest/stopTest, System.runAs, Assert Methods). Whether you're preparing for interviews, certifications, or building production-grade applications, this cheat sheet covers common mistakes, real-world examples, and shortcut techniques to help you write clean, efficient, and maintainable code.

โšก Apex Best Practices

  • Bulkification - Process multiple records at once
  • Avoid SOQL in Loops - Query outside loops
  • Use Collections - Maps, Sets, Lists
  • Exception Handling - Try-Catch blocks
  • Separation of Concerns - Separate business logic
  • Static Methods - Utility classes
  • Avoid Hardcoding - Custom Labels, Settings
  • Governor Limits - Stay within limits

๐Ÿ” SOQL Best Practices

  • SELECT Required Fields - Only what you need
  • Use WHERE Clauses - Filter at database level
  • Bind Variables - Prevent SOQL injection
  • WITH SECURITY_ENFORCED - Enforce FLS & sharing
  • Use LIMIT - Limit query results
  • FOR Loop - Process query results
  • Avoid Formula Fields - In WHERE clause
  • Selective Queries - Use indexed fields

๐Ÿงช Test Class Best Practices

  • @isTest - Mark test classes
  • Test.startTest/stopTest - Isolate execution
  • System.runAs() - Test user permissions
  • SeeAllData=False - Isolated test data
  • Assert Methods - Verify outcomes
  • @testSetup - Create test data
  • Test Positive/Negative - Both scenarios
  • Bulk Testing - Test bulk scenarios

๐Ÿšซ Common Mistakes

  • SOQL in Loops - Governor limit violation
  • Hardcoding IDs - Use constants
  • Nested Loops - Performance issues
  • Inefficient DML - DML in loops
  • No Exception Handling - Unhandled errors
  • No Tests - Code without test coverage
  • SeeAllData=True - Coupled tests
  • No Bulk Testing - Fails in production

๐Ÿ“Š Governor Limits

  • SOQL Queries - 100 per transaction
  • DML Statements - 150 per transaction
  • Heap Size - 6 MB (Sync) / 12 MB (Async)
  • CPU Time - 10,000 ms
  • Records - 50,000 per DML
  • Total Records - 10,000 (Sync) / 50,000 (Async)
  • SOQL Rows - 50,000 rows
  • Callouts - 100 per transaction

๐Ÿ Key Takeaways

  • Think Bulk - Always process multiple records
  • Query Outside Loops - Fetch once, use many
  • Use Maps - For efficient lookups
  • Test Everything - 75%+ coverage required
  • Security First - WITH SECURITY_ENFORCED
  • Handle Exceptions - Always use try-catch
  • No Hardcoding - Use Custom Labels/Settings
  • Optimize Queries - Use selective filters

โšก Bulk

Process multiple records

Always think bulk

๐Ÿ” SOQL

Query outside loops

Use Bind Variables

๐Ÿงช Tests

@isTest annotation

75%+ coverage

๐Ÿšซ Avoid

SOQL in loops

Hardcoding

โšก Apex Best Practices

๐Ÿ“Œ Practice
  • Bulkification
  • Avoid SOQL in Loops
  • Use Collections
  • Exception Handling
  • Separation of Concerns
  • Static Methods
  • Avoid Hardcoding
  • Governor Limits
๐Ÿ“ Description
  • Process multiple records at once
  • Query outside loops to avoid governor limits
  • Maps, Sets, Lists for efficient data handling
  • Try-Catch blocks for error handling
  • Separate business logic from triggers
  • Use utility classes for common operations
  • Use Custom Labels, Custom Settings, Custom Metadata
  • Stay within limits
๐Ÿ’ก Example
  • DML on List not one by one
  • Map accMap = new Map();
  • Map accMap = new Map();
  • try { ... } catch (Exception e) { ... }
  • Use Handler classes
  • public static void updateAccounts()
  • CustomLabel__c or Custom_Setting__c
  • SOQL queries โ‰ค 100 per transaction
โœ… Check
  • Always process List
  • No SOQL inside for loops
  • Use Map for lookups
  • Catch all exceptions
  • Separate logic from triggers
  • Use static for utilities
  • No hardcoded IDs
  • Monitor CPU, Heap, Query limits

๐Ÿ” SOQL Best Practices

๐Ÿ“Œ Practice
  • SELECT Required Fields
  • Use WHERE Clauses
  • Use Bind Variables
  • WITH SECURITY_ENFORCED
  • Use LIMIT
  • Use FOR Loop
  • Avoid Formula Fields in WHERE
  • Selective Queries
๐Ÿ“ Description
  • Only query fields you need
  • Filter data at database level
  • Prevent SOQL injection
  • Enforce FLS and sharing rules
  • Limit query results
  • Efficiently process query results
  • Formula fields can't use indexes
  • Use indexed fields for filtering
๐Ÿ’ก Example
  • SELECT Id, Name FROM Account
  • WHERE Name LIKE 'Acme%'
  • :accountName
  • SELECT Id FROM Account WITH SECURITY_ENFORCED
  • LIMIT 10000
  • for (Account acc : [SELECT Id FROM Account])
  • Avoid: WHERE Discount__c > 10
  • Use fields with indexes
โœ… Check
  • No SELECT *
  • Filter in query
  • Use :variable
  • Always use WITH SECURITY_ENFORCED
  • Limit results
  • Use for loops
  • Check field indexes
  • Use custom indexes

๐Ÿงช Test Class Best Practices

๐Ÿ“Œ Practice ๐Ÿ“ Description ๐Ÿ’ก Example
@isTest Annotation Mark test classes and methods @isTest class MyTest { }
Test.startTest/stopTest Isolate test execution Test.startTest(); // code Test.stopTest();
System.runAs() Test with different user permissions System.runAs(user) { // code }
SeeAllData=False Create isolated test data @isTest(SeeAllData=false)
Assert Methods Verify expected outcomes System.assertEquals(expected, actual);
@testSetup Create test data once, reuse @testSetup static void setup() { }
Test Positive/Negative Test both success and failure Test positive: success, negative: failure
Bulk Testing Test bulk scenarios List accounts = new List();
Test.setMock() Mock external API calls Test.setMock(WebServiceMock.class, new MyMock());
Database.Saveresult Test DML partial success Database.SaveResult[] results = Database.insert(records, false);

๐Ÿ“Š Governor Limits

๐Ÿ“Œ Limit
  • SOQL Queries
  • DML Statements
  • Heap Size (Sync)
  • Heap Size (Async)
  • CPU Time
  • Records per DML
  • Total Records (Sync)
  • Total Records (Async)
  • SOQL Rows
  • Callouts
๐Ÿ“ Limit Value
  • 100 per transaction
  • 150 per transaction
  • 6 MB
  • 12 MB
  • 10,000 ms
  • 50,000 per DML
  • 10,000 records
  • 50,000 records
  • 50,000 rows
  • 100 per transaction
๐Ÿ’ก Best Practice
  • Query outside loops
  • Batch DML operations
  • Use efficient data types
  • Monitor heap usage
  • Optimize code performance
  • Batch processing
  • Use Batch Apex
  • Use Batch Apex
  • Use LIMIT and WHERE
  • Use async callouts

๐Ÿšซ Common Mistakes to Avoid

โŒ Mistake
  • SOQL in Loops
  • Hardcoding IDs
  • Nested Loops
  • Inefficient DML
  • No Exception Handling
  • No Tests
  • SeeAllData=True
  • No Bulk Testing
  • No Security Enforcement
  • Formula Fields in WHERE
โš ๏ธ Problem
  • Governor limit violation
  • Fails in different orgs
  • Performance issues
  • DML limit exceeded
  • Unhandled errors
  • No test coverage
  • Couples tests to org data
  • Fails in production
  • Security vulnerabilities
  • No index usage
โœ… Solution
  • Query outside loops
  • Use Constants or Custom Settings
  • Use Maps for lookups
  • Batch DML operations
  • Try-Catch blocks
  • Write test classes
  • SeeAllData=False
  • Test with bulk data
  • WITH SECURITY_ENFORCED
  • Use indexed fields
๐Ÿ’ก Example
  • Map accMap = new Map();
  • final String ACCOUNT_ID = '001...';
  • for (Id key : map.keySet())
  • Database.update(accounts, false);
  • try { } catch (Exception e) { }
  • @isTest class MyTest { }
  • @isTest(SeeAllData=false)
  • List accounts = new List();
  • SELECT Id FROM Account WITH SECURITY_ENFORCED
  • WHERE CreatedDate = TODAY

๐Ÿ’ป Real-World Examples

// โœ… GOOD: Bulkified Trigger Handler
public class AccountTriggerHandler {
    public static void updateRelatedContacts(List newList) {
        // Query once outside loop
        Map accMap = new Map(newList);
        List contactsToUpdate = new List();
        
        for (Contact con : [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accMap.keySet()]) {
            con.AccountId = accMap.get(con.AccountId).Id;
            contactsToUpdate.add(con);
        }
        
        if (!contactsToUpdate.isEmpty()) {
            try {
                update contactsToUpdate; // Single DML
            } catch (Exception e) {
                System.debug(e.getMessage());
            }
        }
    }
}

// โœ… GOOD: SOQL with Security Enforcement
List accounts = [SELECT Id, Name FROM Account WITH SECURITY_ENFORCED];

// โœ… GOOD: Test Class
@isTest
public class AccountTest {
    @testSetup
    static void setup() {
        Account acc = new Account(Name = 'Test');
        insert acc;
    }
    
    @isTest
    static void testBulkify() {
        List testAccounts = new List();
        for (Integer i = 0; i < 200; i++) {
            testAccounts.add(new Account(Name = 'Bulk' + i));
        }
        
        Test.startTest();
        insert testAccounts;
        Test.stopTest();
        
        List results = [SELECT Id FROM Account WHERE Name LIKE 'Bulk%'];
        System.assertEquals(200, results.size());
    }
}

๐ŸŽฏ Best Practices Quick Revision

The Golden Rule: Always think bulk, query outside loops, use collections, and test everything. Security and performance are the foundation of production-grade Salesforce applications.

Quick Memory Tricks:

  • ๐Ÿ“Œ Apex: "Bulk, Collections, Exception, Separation"
  • ๐Ÿ“Œ SOQL: "Selective, Security, Bind, Limit"
  • ๐Ÿ“Œ Tests: "Isolated, Assert, Setup, Bulk"
  • ๐Ÿ“Œ Limits: "100 Queries, 150 DML, 50k Rows"
  • ๐Ÿ“Œ Security: "WITH SECURITY_ENFORCED, FLS, Sharing"

Checklist Before Deployment:

  • โœ… No SOQL/SOSL in loops
  • โœ… DML operations are bulkified
  • โœ… Exception handling for all DML
  • โœ… No hardcoded IDs
  • โœ… WITH SECURITY_ENFORCED for all SOQL
  • โœ… Test coverage โ‰ฅ 75%
  • โœ… All test methods use SeeAllData=False
  • โœ… Bulk scenarios tested
  • โœ… Governor limits not exceeded
  • โœ… Code is optimized for performance

๐Ÿ’ก Pro Tips for Best Practices

โœ… Always Think Bulk

Salesforce processes records in batches. Always design code that works with collections, not individual records.

โœ… Query Once, Use Many

Fetch all required data in a single SOQL query, then use Maps for efficient lookups throughout the transaction.

โœ… Test Everything

Test positive scenarios (success), negative scenarios (failure), and bulk scenarios (large data sets).

โœ… Use Security Enforcement

Always use WITH SECURITY_ENFORCED in SOQL queries to enforce FLS and sharing rules.

โœ… Handle Exceptions Gracefully

Always use try-catch blocks for DML operations and external calls. Log errors and show user-friendly messages.

โœ… Write Readable Code

Use meaningful variable names, add comments for complex logic, and follow Salesforce coding conventions.

๐Ÿ“‹ Quick Reference: Common Mistakes Summary

โŒ Mistake
  • SOQL in Loops
  • Hardcoding IDs
  • Nested Loops
  • Inefficient DML
  • No Exception Handling
  • No Tests
  • SeeAllData=True
  • No Bulk Testing
  • No Security Enforcement
  • Formula Fields in WHERE
โš ๏ธ Risk
  • Governor Limit Violation
  • Breaks in Different Orgs
  • Performance Issues
  • DML Limit Exceeded
  • Unhandled Errors
  • No Test Coverage
  • Test Data Dependency
  • Fails in Production
  • Security Vulnerability
  • No Index Usage
โœ… Fix
  • Query Outside Loops
  • Use Constants/Custom Settings
  • Use Maps for Lookups
  • Batch DML Operations
  • Try-Catch Blocks
  • Write Test Classes
  • SeeAllData=False
  • Test with Bulk Data
  • WITH SECURITY_ENFORCED
  • Use Indexed Fields

๐Ÿ” Quick Reference: SOQL Best Practices

๐Ÿ“Œ Practice
  • SELECT Required Fields
  • Use WHERE Clauses
  • Use Bind Variables
  • WITH SECURITY_ENFORCED
  • Use LIMIT
  • Use FOR Loop
  • Use IN Operator
  • Avoid Formula Fields
๐Ÿ“ Why
  • Reduce heap usage
  • Filter at database level
  • Prevent SOQL injection
  • Enforce FLS and sharing
  • Limit results
  • Efficient processing
  • Filter by multiple values
  • Can't use indexes
๐Ÿ’ก Example
  • SELECT Id, Name FROM Account
  • WHERE Name LIKE 'Acme%'
  • :accountName
  • WITH SECURITY_ENFORCED
  • LIMIT 10000
  • for (Account a : [SELECT Id FROM Account])
  • WHERE Id IN :idSet
  • WHERE Discount__c > 10
โœ… Check
  • No SELECT *
  • Filter in query
  • Use :variable
  • Always use
  • Limit results
  • Use for loops
  • Use Sets
  • Check field indexes

Topics Covered

salesforce apex best-practices soql test-class governor-limits bulkification security salesforce-developer interview-prep sfdc

Download Cheat Sheet

Click the button below to download this high-resolution PNG cheat sheet.

Download PNG (1 MB)

Preview

Salesforce Apex, SOQL & Test Class Best Practices Preview
Click to enlarge

Still have questions?

We're here to help! Reach out to our support team for any queries.

Contact Us