.ultrageek. Computers, Music, and Thoughts


Too many SOQL queries: 101 even when using testSetup

I am a huge fan of creating global test classes within Salesforce that leverage one testSetup section to set up the data that then can be used many times to test the many different methods and classes. Gone are the days of having a million test classes to manage and update every time changes are made in the system. I've been using this for over a year and as my classes have continued to grow in size and complexity I have run against one limitation that I was unaware of until recently. DML limits are reset when using testSetup but not SOQL limits. Specifically if when you insert a record if that DML generates SOQL statements, which I have a lot of code that relates and joins data, that limit is passed on to the test methods. I think because my test classes are segmented in to major functions I was not running in to a lot of overlap.

In reading the below StackExchange answer it is clear now that all of my test methods need to use Test.startTest() and Test.stopTest(). I always use these methods for scheduled or future class testing but now it is clear that I should be more diligent in always using them.

The tasty bits:

NOTE: If your org has events that are triggered from that INSERT (which you likely do), THEN any DML or SOQL statement that proceeds from those are considered outside the context of @testSetup and will impact your overall governing limits for your test class.

As always these limits are reset within any test method when you invoke Test.startTest(); and Test.stopTest(); but this could affect how much data you can setup within your data setup method (for example when cascading dependencies like Contacts, which need Accounts).



Silly Admin Trick: List of all Objects

Do the following to get a list of Objects by their API names:

  1. Pop in to Workbench
  2. Run the following query:SELECT SobjectType FROM ObjectPermissions
  3. Click Bulk CSV to download
  4. Click the query button to execute
  5. Open in Excel and Dedupe

A quick and easy way to generating a list for creating backups using 'Backup-force.com': https://github.com/neowit/backup-force.com


Backing up Salesforce.com Meta Data on a Mac

There are a couple solutions both paid and free for backing up your Salesforce.com Metadata in addition to using an IDE like Eclipse.

If you need something 'free' and on a schedule the best solution I have found has been:

Alan Morey's Force Meta Backup

To use this tool though there's a couple of prereq's that have to be loaded:

  • Java Runtime (JRE)
  • Apache Ant
  • Groovy

I have used this solution for years and Window's has been my go to in the past due to usually using a VM...

So how to do this easily and quickly on a Mac?

Install the following: Home Brew which is a package manager for MacOS X

Once installed run the following commands (assuming you have admin to your machine):

  • brew cask install java
    • This will install the Java JRE
  • brew install ant
    • This installs Ant
  • brew install groovy
    • This installs...groovy

Now you just need to:

  • Download and Unzip the Force-Meta-Backup from the link above
  • Make a copy of the build.sample.properties file
  • Rename build.sample.properties to build.properties
  • Edit build.properties
  • Add username and password
  • Validate Production or Sandbox
  • Run the following command: ant backupMetadata

This will create a folder called 'Build' which is where all of your Salesforce.com instance metadata will get backed up to. My recommendations when automating is to only zip up (7zip of course) the folders you need as you will get documents folder which can be a bit hefty to archive constantly.


Silly Admin Trick: Finding Active ‘Frozen’ Users in Salesforce.com

One gap with freezing users in Salesforce.com is the ability to go back and find those users. Google is your friend for finding the answer. There's even an article from Salesforce: How can I tell what Users are Frozen via the API?

The below is my take on it. Use workbench/bulk/csv to create an exportable list that you can action.


Tagged as: , , , No Comments

Clicking Link in Email Opens Blank Chrome Tab

Restart Chrome...it has an update that has been applied. Click Help -> About to validate but this issue drove me nuts and since I work on a Mac that only needs rebooting when the VPN crashes (1-4 weeks) I was periodically suffering through this one. It is amazing how long you can deal with a problem until you finally have had enough and google it.

Filed under: Knowledge, Stupid No Comments

Find the API Name from the Field Label

I recently had a use case where I was going to take a drop down value and use that to pull a value from a separate lookup object. I would have "Hourly" and my logic would return "Hourly__c" which I could then use dynamic SOQL and sObjects to do some magic. I did not want to use hardcoded values or a custom setting lookup table and I thought it would be easy to query the metadata...which turned out to be strangely harder than I thought it would be so here is a working solution:

There are a lot of examples of getting the Label from the API name but not really the other way around.


Salesforce.com Icons

No school like the old school. A quick way to give quick visual feedback in the Classic Salesforce.com UI is to use the built-in icons in conjunction with a formula field. A source that I have used forever seems to work and then not work so I found another URL that seems to work:


Basic Formula I used recently to let the user know that the future class had not updated the page with Approval Updates (Status/Step):

if(Update_Status_Text__c = "Future",
/* Page has not been updated by the future class */
IMAGE("/img/msg_icons/error16.png", "Refresh!") &
" Refresh Page",
/* All Good! */
IMAGE("/img/msg_icons/confirm16.png", "All Good!") &
" Page Good!"

This is the original page I've used for years: http://www.force2b.net/index.php/2010/08/salesforce-icons/

Update (Feb 2018): Here's another good site: http://salesforce-stuff.blogspot.com/2012/01/salesforce-images.html

Tagged as: , No Comments

Quick Tip: CSVFIX Duplicate Column

One tool I use to do bulk data loads in to Salesforce.com does not allow mapping one source to multiple destination fields. You can of course use workflows or code to backfill the data once it gets in but a cheaper/easier alternative if it is just one field is the following:

  • csvfix eval -e "if($1!='',$1,$1)" etl_temp.csv > etl_temp2.csv

It is a bit of a hack but basically as long as there is a value in the column it copies it to the last column. $1 is the field position of that row, != is the not equals, and two single quotes for 'Empty String'. The if statement uses double quotes for windows, use single quotes for non-windows.


Custom Settings Fun

Custom Settings are one of the great ways a developer can give admins power to update logic, settings, and the behaviour of code and really make code more flexible.

This is just a quick reference of all the cool ways you can pull those settings back out without having to use a SOQL statement.

This method loads all of the custom settings in to a list:
list<Customer_Setting_Name__c> buList =Customer_Setting_Name__c.getall().values();

This method loads a record using the name as a filter. This of course assumes you are not loading duplicate names:
Customer_Setting_Name__c aplo =Customer_Setting_Name__c.getValues(filter_string); // filter_string is just a string passed in

And finally, this method loads all of the custom settings in to a map with the name as the key:
Map<String,Customer_Setting_Name__c> buMap =Customer_Setting_Name__c.getAll();

The great thing is that these do not take a SOQL hit and admin can update these.

Some of the uses I use this for:

  • Mapping Business Unit settings for Lead Queue's, record types, groups, etc.
  • Multi-dimensional Pick lists that need to shared across objects, enabled/disabled (Global Picklists have taken the place of a lot of these), and that require additional attributes but maybe don't warrant the need for a full custom object IE security.
  • For 'quick disable' functionality for when I want to put code in production that might need to be quickly disabled



Test Classes with Global Picklists

Global Picklists or as Salesforce.com likes to refer to them, "Picklist Value Sets" from the menu or "Global Value Sets" in change sets, are not new but my dealings with them are. Specifically in Apex and test classes with a parent/child relationship using Global Picklists.

Global picklists btw do not have the same limitations normal picklists have in terms of the 1,000 character limitation that previous you had to use record types or a custom solution to get around.

So when you get the following error message in your test class testings: "INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST, bad value for restricted picklist field". What this means is that under the user you are running the test under is not configured to use the values you have populated in the test class. Usually because the test is running under system and is using the master record type that does not have the field mappings. That is my guess at least.

Two ways to fix:

  • Set the RecordTypeId in the test data either statically or dynamically through a variable and a soql lookup using the name/developer name
  • Use the System.runAs(thisUser) method to either run as the user running the test or create a user with a specifically assigned profile that has the correct privileges and set up.

Below are examples: