Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

We are facing couple of issue with Unit Test methods.

  1. SOQL queries limit hits before "Test.StartTest()". We want to test a batch process and it needs to creates records for around 8 to 10 objects which has triggers. Because of that it is throwing limit exception before "Test.StartTest()".

Below is example of code.

@isTest
private class Test_Trigger_Contact
 {
     static testMethod void test1() 
     {        
       Student__c  studentToAdd; 
       List<Contact> contacts= new List<Contact>();  

      // To create Test data we are creating some test records of around 8-10 objects.
      // Internally it fires trigger and consumes diffrent SOQL queries, which cross 101 SOQL limit.
      // Because of this our test class fails before "Test.StartTest()"/"Test.StopTest()".
       for(integer i=0;i<101;i++)
         {
               contacts= [SELECT Id,Name FROM   Contact];

         }        
       test.startTest();
      // Do Some Unit Test for a batch process
      test.stopTest();
     }
 }
  1. Another problem is, Salesforce is not resetting the Governor limit inside "Test.StartTest()" and "Test.StopTest()". Which is mentioned on below Salesforce issue.

https://success.salesforce.com/issues_view?id=a1p30000000T5R5AAK

With below example, you can reproduce this issue :

 @isTest
 private class Test_Trigger_Contact
 {
     static testMethod void test1() 
     {        
       Student__c  studentToAdd; 
       List<Contact> contacts= new List<Contact>();  

      // Below code is consuming 98 queries to generate Test Data
       for(integer i=0;i<98;i++)
         {
               contacts= [SELECT Id,Name FROM   Contact];

         }   
      // After that we are using "test.startTest()", to reset governer imit.
      // But it doesn't and throws 101 SOQL query error.
       test.startTest();
      // Do Some Unit Test for a batch process
       for(integer i=0;i<3;i++)
       {
               contacts= [SELECT Id,Name FROM   Contact];

         }  
      test.stopTest();
     }
 }

2nd issue will be fixed with Salesforce release as mentioned on above link.

I am not sure how can we fix 1st issue. Where we need to generate large data to test Batch Process. My understanding was, Salesforce calculates governor limits only inside "Test.startTest()" and "Test.stopTest()" for unit Test method and it doesn't calculates it while generating test data. Can someone please confirm my understanding regarding?

Thanks and Regards, Ashish Shukla

share|improve this question
    
AFAIK, Test.startTest() should give you a new set of governor limits, but that does not mean that anything before it is ignored. I don't have the source to prove that ATM though – mkorman Jan 14 at 10:18
up vote 6 down vote accepted

By using the Test.startTest() & Test.stopTest() you get 2X governer limits.

In nutshell you have 2 context.
1) out side of Test.startTest() & Test.stopTest() and
2) inside of Test.startTest() & Test.stopTest().

In both context you get separate limits.

To fix this issue what you will have to do is:
1) Optimize and see if you can reduce the queries in trigger
2) Reduce the number of objects you are inserting
3) You can skip unnecessary trigger execution by checking if trigger being called by Test method if(Test.isRunningTest())
4) in worst case you can use SeeAllData = ture

share|improve this answer
    
Thanks a lot Atul, it looks like a good solution. – Ashish Shukla Jan 14 at 10:37

This issue (SOQL Limit not resetting in Test.StartTest() & Test.StopTest()) is now fixed and the details can be found on below link : https://success.salesforce.com/issues_view?id=a1p30000000T5R5AAK

share|improve this answer

Something to add to AtulRajguru9's answer is that you should bulkify your assignment and the trigger as well if it hasn't been. What that means is take the SOQL statement out of the loop and get all the records you need in one statement. I can't tell with the code you've provided, but the simplest way to do this is to use dynamic queries to build a string finding each ID, as in Database.Query('select ID, name from Contact where ID = \'' + id1 + '\' or ID = \'' + id2...); (Of course, this would make more sense to be built in a loop). Similarly with DML, insert or update a whole list of records at once and make sure your triggers support it, don't run one update statement per loop iteration.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.