function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
calvin_nrcalvin_nr 

Best practices to avoid governor limit for SOQL queries with Test classes

Hi folks,

 

I have not been able to get any reliable information about this issue online. But I think it must be an issue which must be affecting a lot of people.

 

Basically I wrote a simple trigger and test class in sandbox, tested it and when it was fine I deployed it to PRD.

I tried the validation mode first and I got this error.

 

System.LimitException: Too many SOQL queries: 101

 

This error was shown to occur in some other test class. So I feel that the test cases in my trigger ran and this coupled with the remaining test cases somehow overshot the limit.

 

So the total number of SOQL queries in our unit tests must be less than 100. This is a little hard to adere to right? I can imagine with so many test cases, surely we will need more than 100 queries.

 

So what are the ways to avoid hitting this limit because Salesforce runs all the test cases when deploying even a single line of code.

 

I dont not have any of the usual suspects...like SOQL within a for loop.

 

Can you please share your thoughts?

 

Thanks,

Calvin

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

If you run the test class that fails in production when your trigger is deploying, you should be able to access the debug log for that and see how close to the governor limit it is already.

All Answers

bob_buzzardbob_buzzard

Its not a limit of 100 across all test classes, its a limit of 100 per test.

 

Do you have a number of soql calls consumed to set up test data for this particular test case?

calvin_nrcalvin_nr

Thanks Bob.

 

But the puzzling thing is when I just run all tests in salesforce production today, the test cases work fine including the test class which is flagged as an error when I try deploying my test class into production.

 

It is as if things are fine till I move my class in as it it is tipping the scale over. But my test class cannot possibly be running more than 100 times. That being said, the existing test class is pretty huge but it is not having any issues as of today.

 

I am putting the code of my test class just in case:

 

@isTest
private class TestAccountDuplicateWebsiteTrigger {

    
    static testMethod void myUnitTest() {
    	try{
        // TO DO: implement unit test
        Account a1;      
        a1 = new Account();
		a1.name = 'GMSTest';	
		a1.Website = 'www.test.com';	        
		
		 
		
        Account a2;      
        a2 = new Account();
		a2.name = 'GMSTest2';	
		a2.Website = 'www.test.com';	        
		
        
        Account a3;      
        a3 = new Account();
		a3.name = 'GMSTest3';	
		a3.Website = 'www.test1.com';	        
		
		
		insert a1;
		insert a2;
		insert a3;
		
		
    	}
    	catch (Exception e)
    	{
    	}
    	
    }
}

 

 trigger being tested:

 

trigger osv_unique_website_for_account on Account (before insert, before update) {	
	
		//Map which has no duplicates with website as the key
		Map<String, Account> accountMap = new Map<String, Account>();
		
		for (Account account: System.Trigger.new)
		{
			//Ensure that during an update, if an website does not change - it should not be treated as a duplicate
			if ((account.Website != null) && (System.Trigger.isInsert ||			
				(account.Website != System.Trigger.oldMap.get(account.Id).Website))) 
				{
					//check for duplicates among the new accounts in case of a batch
					 if (accountMap.containsKey(account.Website)) 
					 {
	                	account.Website.addError('Cannot save account. Website already exists.');
	            	 } 
	            	 else 
	            	 {
						accountMap.put(account.Website, account);
	            	 }
					
				}		
		}
		
		//Now map containing new account websites has been created. 
		//Check them against the account websites that ALREADY EXIST in salesforce. If website exists, display error.
		for (Account account : [SELECT Website FROM Account WHERE Website IN :accountMap.KeySet()]) 
		{
			Account newAccount = accountMap.get(Account.Website);
			if (newAccount!=null)
			{
				newAccount.Website.addError('Cannot save account. Website already exists.');
			}
		}	
	
	
	
}

 

 

 

 

 

Starz26Starz26

You class may be the one that goes over the limit but it is not the problem.

 

I would review the triggers in production to ensure that they are not written poorly.

 

Use the developer console in Production and run your test class. Mainly create and insert 3 accounts. See how many SOQL are being executed and trace from there.

hisalesforcehisalesforce

You can use test.starttest() and test.stoptest() in between the test code.

This will refresh the SoQl limit in the method of test class.

Try to use in the middle of the test  method .

bob_buzzardbob_buzzard

The other test classes run in their own test context, so your test class won't be having any effect on them.  Are you just deploying a test class or are you deploying some code too (a new trigger, maybe).  It sounds like your deployment is adding to the total soql calls for a transaction.

calvin_nrcalvin_nr

Hi Bob,

 

Yes I am deploying the class and trigger as I have posted above.

 

I added the startTest() and Stoptest() to no avail.

I am still getting the same error moving these two to production.

 

I tried moving some code I moved last week. That got validated without any issue.

 

Thanks,
Calvin

calvin_nrcalvin_nr

Hey StarZ,

 

How do I point my dev console to production and test a class that has not yet been deployed there.

 

Thanks.

bob_buzzardbob_buzzard

If you run the test class that fails in production when your trigger is deploying, you should be able to access the debug log for that and see how close to the governor limit it is already.

This was selected as the best answer
hisalesforcehisalesforce

Its not always necessary that you are getting exception for your class only.

Check the error message and figure out for which class its getting soql exception.

Whichever class you are getting this error use test.starttest().

Check whether you are using DML in loop or not .

If its on loop then put in list and use only one DML.

 

If not working you have two option:

 

1.Comment some the dml query and  to deploy it again.This will decrease the code coverage but will work to deploy.But sometime that particular soql will not effect so much for the code coverage.If its pulling the code coverage very low then go to option 2:

 

2.This is the best  way to solve it.Make a new test method in the same class and  put some of the soql in that method .This will allow to make a lot more SOQL. 

 

calvin_nrcalvin_nr

Trying out a deployment on validation mode with the Force.com IDE helped me figure out which existing method had the issue. I surrounded the DML statements with Test.StartTest() and Test.StopTest() and the deployment worked.

 

Thanks.