Every Salesforce developer knows the rule: 75% code coverage minimum for deployment. But hitting that number doesn't mean your code is tested—it just means you've written enough lines to satisfy the platform.
We've seen orgs with 90%+ coverage that still break in production because tests don't validate business logic, edge cases, or integration points. Here's how to write tests that actually matter.
The Testing Pyramid
Effective testing follows a pyramid structure:
- Unit Tests (70%): Fast, isolated tests of individual methods
- Integration Tests (20%): Tests that verify components work together
- End-to-End Tests (10%): Full user workflow tests
Writing Meaningful Unit Tests
Test the Business Logic, Not Just the Code
Your tests should verify that your code does what it's supposed to do, not just that it runs without errors.
public class AccountTriggerHandler {
public static void calculateAnnualRevenue(List<Account> accounts) {
for (Account acc : accounts) {
if (acc.NumberOfEmployees > 100) {
acc.AnnualRevenue = acc.AnnualRevenue * 1.1; // 10% boost
}
}
}
}
@isTest
private class AccountTriggerHandlerTest {
@isTest
static void testCalculateAnnualRevenue_LargeCompany() {
// Given: Account with 150 employees and $1M revenue
Account acc = new Account(
Name = 'Test Corp',
NumberOfEmployees = 150,
AnnualRevenue = 1000000
);
// When: Calculate revenue
AccountTriggerHandler.calculateAnnualRevenue(new List<Account>{acc});
// Then: Revenue should be increased by 10%
System.assertEquals(1100000, acc.AnnualRevenue,
'Large companies should get 10% revenue boost');
}
@isTest
static void testCalculateAnnualRevenue_SmallCompany() {
// Given: Account with 50 employees
Account acc = new Account(
Name = 'Small Corp',
NumberOfEmployees = 50,
AnnualRevenue = 1000000
);
// When: Calculate revenue
AccountTriggerHandler.calculateAnnualRevenue(new List<Account>{acc});
// Then: Revenue should remain unchanged
System.assertEquals(1000000, acc.AnnualRevenue,
'Small companies should not get revenue boost');
}
}
Testing Edge Cases
Don't just test the happy path. Test what happens when:
- Null values are passed
- Empty lists are processed
- Governor limits are approached
- Related records don't exist
- Validation rules should prevent the operation
Testing Bulk Operations
Salesforce processes records in batches. Your tests should verify bulkification works correctly.
Mocking External Dependencies
When testing code that makes callouts or queries external data, use test classes and mock responses.
Test Data Management
Use @TestSetup to create test data once, then reference it in multiple test methods. This improves performance and maintainability.
Best Practices
- ✅ One assertion per test method (when possible)
- ✅ Use descriptive test method names:
testMethodName_Scenario_ExpectedResult - ✅ Test both positive and negative cases
- ✅ Verify governor limit usage in tests
- ✅ Test with realistic data volumes
- ✅ Keep tests fast—they should run in seconds, not minutes
Struggling with test coverage or quality? We can help you build a comprehensive testing strategy. Get in touch.
#TBR