Test.startTest()
makes all asynchronous calls synchronous (instant) in Test methods. It helps us in catch any result obtained by the execution of asynchronous calls.
Below is sample example:-
Test define One future and batch class:-
Future:
public class FutureCallClassMethod
{
@future
public static void futureCall()
{
Account acc = new Account(Name='Future Call');
insert acc;
System.debug(' Position 1: Account is created in Future: '+acc);
}
public static void BatchCall()
{
Database.executeBatch(new BatchClassSample());
System.debug(' Position 2: Batch executed');
}
}
Batch class:-
global class BatchClassSample implements Database.Batchable<sObject>{
global final String Query;
global final String Entity;
global final String Field;
global final String Value;
global BatchClassSample(){
Query='SELECT id FROM Account Limit 10';
}
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<sObject> scope) {
Account acc = new Account(Name='Batch Call');
insert acc;
System.debug(' ==> Position 1 in Batch class: '+scope);
}
global void finish(Database.BatchableContext BC){
}
}
Test class:-
@isTest
public class FutureCallClassMethodTest
{
public static testmethod void runFuture()
{
FutureCallClassMethod.futureCall();
List<Account> acc = [SELECT Id, Name from Account];
System.debug(' ==> Position 2: Future without Test.startTest: '+acc);
}
public static testmethod void runFutureWithTest()
{
Test.startTest();
FutureCallClassMethod.futureCall();
Test.stopTest();
List<Account> acc = [SELECT Id, Name from Account];
System.debug(' ==> Position 2: Future with Test.startTest: '+acc);
}
public static testmethod void runBatch()
{
Account accTest = new Account(Name='Test Account');
insert accTest;
FutureCallClassMethod.batchCall();
List<Account> acc = [SELECT Id, Name from Account WHERE Name!='Test Account'];
System.debug(' ==> Position 3: Batch without Test.startTest: '+acc);
}
public static testmethod void runBatchWithTest()
{
Account accTest = new Account(Name='Test Account');
insert accTest;
Test.startTest();
FutureCallClassMethod.batchCall();
Test.stopTest();
List<Account> acc = [SELECT Id, Name from Account WHERE Name!='Test Account'];
System.debug(' ==> Position 3: Batch with Test.startTest: '+acc);
}
}
When you execute the class you can clearly see that:-
Without Test.startTest
, asynchronous code executes in last and the no account records was found when we queried that records in test class.
With Test.startTest
asynchronous operation executes in series and result also obtained in test class.
These can be seen in debugs as well. We get zero result of asynchronous operation without Test.StartTest
. And these executed in last.

Everything executes but their sequence changes.
Test.stopTest()