When to use Test.startTest?
Test.startTest()
and Test.stopTest()
exist primarily to allow you to reset the governor limits within the context of your test execution and to be able to test asynchronous methods. These two statements cannot be called more than once within a testMethod. They are not required to be used but in some situations may be critical. Asynchronous (@future
) calls made during the test are also finalized when you call Test.stopTest()
allowing you to test the results of asynchronous behavior in your code.
Given a scenario where you need to execute numerous queries and a large number of DML rows in order to set up the data for the actual code being tested, it might be impossible for you to run your test without these statements.
For instance in this fictional scenario, if during the setup of your test you needed to execute 99 SOQL queries and insert 9,999 records to seed the org with the data your code required for proper testing, if Salesforce did not offer a mechanism to reset the governor limits the code which you are testing would only have room for one more SOQL query and one more record in a DML statement before it would hit one of those two limits (100 queries and 10,000 records processed by DML statements respectively) and throw an exception.
In the above scenario, if you were to call Test.startTest()
after your 99 queries were complete and your 9,999 rows were DML'd - the transaction limits within your test would be back to zero and at that point the code which you are testing would be running in a context that more closely resembles a single transaction's limits in real life. This mechanism allows you to "ignore" the work that had to be done to set up the test scenario.
First you want to do all of your setup, so anything inserts or updates that you need to do as preperation for the actual test should happen before the Test.startTest()
Then you place the code that you are testing inside the Test.startTest()
and Test.stopTest()
tags.
Finally you put your asserts after the Test.stopTest()
tag.
So if you are testing a single method on an VF Page Controller you would create any necessary records. Set the page, and initialize the Controller, call any other methods that might be necessary before the method you are testing.
Then when you are ready to test your method set the Test.startTest()
then the method you need to test and then the Test.stopTest()
Updated
The tags are not required for testing. You could leave them out and there would be no issues.
What do the tags do? According to Salesforce Documentation...
startTest()
Marks the point in your test code when your test actually begins. Use this method when you are testing governor limits.
Usage
You can also use this method with stopTest to ensure that all asynchronous calls that come after the startTest method are run before doing any assertions or testing. Each test method is allowed to call this method only once. All of the code before this method should be used to initialize variables, populate data structures, and so on, allowing you to set up everything you need to run your test. Any code that executes after the call to startTest and before stopTest is assigned a new set of governor limits.
stopTest()
Marks the point in your test code when your test ends. Use this method in conjunction with the startTest method.
Usage
Each test method is allowed to call this method only once. Any code that executes after the stopTest method is assigned the original limits that were in effect before startTest was called. All asynchronous calls made after the startTest method are collected by the system. When stopTest is executed, all asynchronous processes are run synchronously.
So they basically give you a seperate context for your test as far as governor limits go. Anything before and after the tags use one set of limits, anything in-between get their own set of limits. They also ensure that any asynchronous code that you are testing will finish before any assertions you make in your code.
Salesforce's intention is for you to use them with Asynchronous calls, and when you are worried about hitting limits do to setup and what not.
Again you don't always need them, I however use them in all my tests as a kind of symantic marker to let myself, and those who might come after me looking at my code, to know exactly what I'm attempting to test.