SeeAllData=true is a parameter on the @isTest annotation that lets a test method query and see records that already exist in the org. By default (since API 24.0), tests are isolated — they only see records they create themselves.
@isTest(SeeAllData=true)
static void seesOrgData() {
List<Account> all = [SELECT Id FROM Account];
// Sees every Account in the org, not just ones this test inserted
}
Why it’s almost always wrong
A test exists to verify a contract — given inputs X, produce outputs Y. The inputs should be deterministic; otherwise the test is unreliable. SeeAllData=true breaks determinism in three ways:
1. Tests pass on your machine and fail in CI
Your sandbox has 50 sample Accounts. Your colleague’s sandbox has 200. Your CI org has 0. The same test produces three different results.
2. Tests pass today and fail tomorrow
A user deletes an Account, or a deployment seeds new data. Your test that asserted [SELECT COUNT() FROM Account] == 50 now fails for reasons unrelated to the code change.
3. Tests can have side effects
If your test does Account a = [SELECT Id FROM Account LIMIT 1] and then mutates a, you’ve just changed a real org record. Salesforce rolls back DML at the end of the test, but the data picked was someone else’s — and the test logic depends on whoever owned that record.
When is it acceptable?
Genuinely rare cases:
- You’re testing a
ReportsorDashboardsAPI that operates on org metadata you can’t create from Apex. - You’re inside a managed package and need to read certain platform records (e.g.
User,Profile,Organization) that you can’t create. - You’re working with custom metadata types before API 44.0 (post-44 they can be created in tests directly).
Even then, scope it tight — apply @isTest(SeeAllData=true) to the method, not the class, so the rest of the class stays isolated.
The right pattern: create your own data
@isTest
static void doesTheRightThing() {
Account a = new Account(Name = 'Test Co', Industry = 'Tech');
insert a;
Test.startTest();
AccountService.process(a.Id);
Test.stopTest();
System.assertEquals('Processed', [SELECT Status__c FROM Account WHERE Id = :a.Id].Status__c);
}
This test:
- Works the same in every org
- Doesn’t depend on org state
- Cleans up automatically (DML rollback at the end of the test method)
What about User, Profile, Organization?
Some standard objects can’t be created in tests. The platform exposes them through SeeAllData=true queries even when you don’t set it:
User— can be queried withoutSeeAllData=trueProfile,PermissionSet— queryable withoutSeeAllData=trueOrganization,AsyncApexJob,ApexClass— also exempt
So you can write:
@isTest
static void runsAsAdmin() {
User u = [SELECT Id FROM User WHERE Profile.Name = 'System Administrator' LIMIT 1];
System.runAs(u) { /* ... */ }
}
…without needing SeeAllData=true.
Common interview follow-ups
- Is
SeeAllData=truethe default? — No, it’s beenfalseby default since API 24.0 (Spring ‘12). - Does
SeeAllData=falseblock queries on User? — No; User, Profile, RecordType, and a few others are always visible. - Can a class-level
SeeAllData=falseoverride a method-leveltrue? — No, method-level applies. But class-leveltruedoes apply to every method unless they explicitly say otherwise.
Verified against: Apex Developer Guide — Isolation of Test Data from Organization Data. Last reviewed 2026-05-17 for Spring ‘26 release.