🧪 Mastering Test Classes in Salesforce: A Developer’s Guide
In Salesforce, writing test classes isn’t just a good practice — it’s a requirement. Apex code must be tested before it can be deployed to a production org. Whether you’re new to Apex or aiming to improve your testing skills, this guide covers everything you need to know about writing effective test classes in Salesforce.
🧩 Why Test Classes Matter
Salesforce mandates at least 75% code coverage for deployment to production. But beyond that, good test classes help ensure:
- Code behaves as expected
- Bugs are caught early
- Deployments are safe and predictable
- Future changes won’t break existing functionality
🔍 What is a Test Class?
A test class is a special Apex class that contains methods annotated with @isTest. These methods simulate user and system interactions to validate Apex code logic.
🧱 Anatomy of a Test Class
A good test class typically includes:
- Test Data Setup
- Business Logic Execution
- Assertions (Validations)
🔧 Basic Example
@isTest
private class AccountTriggerTest {
@isTest
static void testActiveAccountDeletion() {
// Step 1: Create test data
Account acc = new Account(Name = ‘Test Account’, IsActive__c = true);
insert acc;
// Step 2: Try to delete the account
Test.startTest();
try {
delete acc;
System.assert(false, ‘Expected exception not thrown’);
} catch (DmlException e) {
System.assert(e.getMessage().contains(‘You cannot delete an Active Account’));
}
Test.stopTest();
}
}
🛠️ Best Practices for Writing Test Classes
Best Practice | Why It Matters |
Use @isTest annotation | Marks the class/method for test execution |
Create your own test data | Avoids reliance on org data |
Use Test.startTest() and Test.stopTest() | Measures performance and simulates user behavior |
Include System.assert() statements | Verifies expected behavior |
Keep tests isolated | Makes debugging and maintenance easier |
Use SeeAllData=false | Ensures test data independence |
📊 Checking Code Coverage
After running tests, go to:
- Developer Console → Test → New Run
- Or use VS Code → SFDX: Run Apex Tests
- Review coverage in Setup → Apex Test Execution
To deploy to production:
- Overall org coverage must be ≥ 75%
- Each class or trigger must be at least partially covered
🤖 Advanced Tips
- Use Test.getStandardPricebookId() when dealing with Products
- Mock callouts using HttpCalloutMock for HTTP integrations
- Use @testSetup method to share data across tests
- Bulk test your triggers by inserting/updating many records
🚫 Common Mistakes to Avoid
Mistake | Impact |
Using real org data | Makes tests unreliable |
Not using assertions | Doesn’t verify functionality |
Testing one scenario only | Misses edge cases |
No bulk testing | Fails in production on bulk operations |
🧪 Example: Testing a Trigger Handler
Imagine a trigger that prevents deleting active Accounts:
public class AccountTriggerHandler {
public static void preventActiveAccountDeletion(List<Account> oldAccounts) {
for (Account acc : oldAccounts) {
if (acc.IsActive__c == true) {
acc.addError(‘You cannot delete an Active Account.’);
}
}
}
}
🔬 Test Class:
private class AccountTriggerHandlerTest {
@isTest
static void testPreventDeletionOfActiveAccount() {
Account acc = new Account(Name = ‘Active Account’, IsActive__c = true);
insert acc;
Test.startTest();
try {
delete acc;
System.assert(false, ‘Expected exception not thrown’);
} catch (DmlException e) {
System.assert(e.getMessage().contains(‘You cannot delete an Active Account’));
}
Test.stopTest();
}
}
🚀 Final Thoughts
Test classes in Salesforce are not just a checkbox for deployment — they’re a powerful tool to ensure your code works correctly today and tomorrow. By writing thoughtful, well-structured tests, you protect your org from unexpected errors and make your development process more robust.