Test Data In 60 Seconds

Test coverage is good practice and is also required in Salesforce Apex. For large complex systems this can be a non-trivial effort as test data becomes more complex to match. In this case setting up test data for your test class can be the majority of your test run. Salesforce does allow you to double the execution limits of your test run using StartTest and StopTest however sometimes that is still not enough.

A clever technique to increase your limits for setting up your test data is to use Futures. A Future is a type of Asynchronous Apex and has 6 times the CPU limit and twice the heap limit as regular Apex. For me CPU was the critical factor that required me to come up with this technique. My client has a system that has many validation rules and required data references for its main domain objects. This requires a lot of data and a lot of CPU time to insert it all even for a simple test.

The snippet below is a test class I have that does a lot of data setup.

Tuan1.png
  1. I use a @testsetup method to set up the same data for all my tests in this test class.

  2. The @testsetup method calls a @future method to take advantage of the higher execution limits in Asynchronous Apex.

  3. Before I load the test data, I disable all triggers. All my triggers use a static flag to continue or discontinue execution.

  4. I use this static utility class to create Sobjects using JSON formatted data stored in static resource files. I use the same class to export data and related data to JSON format and save it to a static resource file.

  5. Turn triggers back on before I execute the tests.

The following debug log shows that the my data setup was about 99% of the execution time.

Tuan2.png
  1. I am over 8 seconds over my execution limit compared to regular Apex which has a maximum CPU time of 10 seconds. But since I am running Asynchronous Apex, my maximum CPU time is 60 seconds which I am still comfortably within.

  2. CreateData method ends at 18122 milliseconds.

  3. First test method begins.

  4. Test only took 416 milliseconds to execute and has maximum CPU time of 10 seconds.

To use Asynchronous Apex with your test class, you need to have your test execute after StopTest as shown below. The StopTest method is a blocking method that will wait for all asynchronous methods to finish executing before continuing. The wait time does not count against your CPU limit as shown above. With this approach you have 60 seconds to create your test data and another 10 seconds to execute your test.

Tuan3.png