Clarify the governor limits with Test.startTest and Test.stopTest

I run the same code in the developer console and here is my debug log:

enter image description here

Here i'm seeing two different no. of soql queries.It is giving me the expected results.Not sure why it is not producing correct results in your case.

EDIT1:

After OP's comment i tested on old versions and OP is right.It is giving the wrong output.It is giving correct one in only version 36.0.

EDIT2:

Just checked the latest release notes and found this:

A block of test code enclosed by the Test.startTest() and Test.stopTest() methods now reliably receives its own block of governor limits. Test.startTest() stores your per-transaction limit counters and temporarily resets them to zero. Test.stopTest() restores your limit counters to pre-Test.startTest() values. When your test method finishes, all per-transaction limits reset to zero. Previously, some limits, such as for SOQL queries, didn’t always reset inside a Test.startTest()/Test.stopTest() block.

So finally we have full proof reason :)

EDIT3:

It's becoming interesting.

I just ran this changed code in old version and found that it hits the soql limit.

for (integer i = 0; i < 100; i++){//running the 100 cycles of loop
        List <account> accts = [select name from Account];
    }
    Test.startTest();
    List <account> accts = [select name from Account];
    system.debug('made it here');
    Test.stopTest();
    system.debug('done');

When you run a unit test, Test.startTest() "sets aside" the testing governor limits, and creates a new set of limits based on the next line of execution. For example, if the next line of code is a DML operation, it sets up a normal trigger execution governor limit, while if it's a Database.exectuteBatch method, it sets the governor limits to the Batchable limits instead.

So, you should definitely see two sets of limits, the former for the queries run outside of Test.startTest() and Test.stopTest(), and those inside. It's possible that since you didn't actually "do" anything inside the actual test phase, you may have caused some sort of bug, but ordinarily, you'd expect to see 99 "outside" queries and 1 "inside" query.

Calling Test.startTest() doesn't "wipe out" the other limits, it only temporarily suspends them.


The correct way to observe such limits is in context.

// 99 queries
Test.startTest();
    system.assertEquals(0, Limits.getQueries());
    // additional query
    system.assertEquals(1, Limits.getQueries());
Test.stopTest();
system.assertEquals(99, Limits.getQueries());

The same holds for other governor limits you wish to rest. Email invocations, DML statements, etc. Note that the value gets reset (to its prior state, not zero) when you call stopTest, so often the last thing you do before such call is cache the limit value.

Tags:

Apex