Test performs DML or async work without Test.startTest()
ID |
apex.correctness.test_start_stop_test |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Test Quality |
Language |
Apex |
Description
Reports a test method that runs DML or enqueues asynchronous work but never calls Test.startTest(). Tests that only build data and assert on it are not reported.
Rationale
Test.startTest() resets the governor limits before the code under test runs, so the setup data the test inserted does not count against the limits of the behaviour being measured - without it, a test that builds 150 records reports a limit failure that says nothing about the code. Test.stopTest() is also what forces queued asynchronous work to finish: without the pair, a @future or Queueable enqueued by the tested code never executes, and the assertions that should have proven it worked pass against an unchanged database.
The following code illustrates the pattern detected by this rule:
@IsTest
private class RenewalServiceTest {
// FLAGGED: Test performs DML or async work without Test.startTest()
@IsTest
static void createsRenewal() {
Account a = new Account(Name = 'Acme');
insert a;
System.assertEquals(1, [SELECT Id FROM Account].size(), 'one account');
}
// FLAGGED: Test performs DML or async work without Test.startTest()
@IsTest
static void enqueuesJob() {
System.enqueueJob(new RenewalJob());
System.assertEquals(1, 1, 'queued');
}
@IsTest
static void createsRenewalWrapped() {
Account a = new Account(Name = 'Acme');
insert a;
Test.startTest();
RenewalService.run(new Set<Id>{ a.Id });
Test.stopTest();
System.assertEquals(1, 1, 'one renewal is created');
}
@IsTest
static void assertsOnly() {
System.assertEquals('Acme', new Account(Name = 'Acme').Name, 'name is set');
}
}