Admin Win: Create Test Data Quickly In a Sandbox

As admins, we test things in Sandboxes (at least, we should be if we’re being good). Sometimes, we do need to test creating records as users, but often times, we need some data to already exist. Here’s how I make that work for me….

For Loops!

It may sound terrifying to write code, but I promise I’m going to give it to you templated out and break it down for you.

In This Blog:

Note: There are lots of ways you can do this, this is just a way that works for me! I found it was easier for me to understand code once I was very familiar with Flow, so I’ve drawn parallels to Flow in the code break down.

Create Data with the Dev Console

Step 1: Open The Developer Console

In case you don’t know how to do that – just hit the setup cog, then “Developer Console”

Setup Cog > Developer Console

Step 2: Open an “Execute Anonymous” Window

Debug > Execute Anonymous

Step 3: Drop this Code in

List<Account> accts = new List<Account>();

        for (Integer i = 0; i < 10; i++){
            Account a = new Account(
                Name = 'Acme #' + i,
                Type = 'Prospect',
                BillingStreet = '415 Mission Street',
                BillingCity = 'San Francisco',
                BillingState = 'CA',
                BillingPostalCode = '94105',
                BillingCountry = 'USA'
            );
            if(i > 5){
                a.Industry = 'Education';
            }
            accts.add(a);
        }

        insert accts;

        List<Contact> cons = new List<Contact>();
        for (Account a : accts){
            for (Integer i = 0; i < 2; i++){
                Contact con = new Contact(
                    AccountId = a.Id,
                    FirstName = 'Test',
                    LastName = 'Smith ' + i
                );
                cons.add(con);
            }            
        }
        insert cons;

In a nutshell, this code is going to let you:

  1. Create Account Records
  2. Create Contact Records for those Accounts

Skip to breaking down the code to learn more

Step 4: Update the code to meet your needs

Your org may have other supporting records needed for an account – and if you need to create them, no problem! Just update every reference of “Contact” to whatever object you need – be sure to also declare a unique variable (as in how my list of accounts is called “accts” while the contact list is “cons”)

TIP: Check out the Trailhead on Apex Basics to learn more about variables


Let’s Break Down the Code

Creating Accounts

The account creation happens in this section of code. Let’s look at it line by line.

List<Account> accts = new List<Account>();

        for (Integer i = 0; i < 10; i++){
            Account a = new Account(
                Name = 'Acme #' + i,
                Type = 'Prospect',
                BillingStreet = '415 Mission Street',
                BillingCity = 'San Francisco',
                BillingState = 'CA',
                BillingPostalCode = '94105',
                BillingCountry = 'USA'
            );
            if(i > 5){
                a.Industry = 'Education';
            }
            accts.add(a);
        }

        insert accts;

List<Account> accts = new List<Account>();

In Line 1, we’re telling Salesforce we want to create a list of Accounts, and we want to call it accts. Easy enough, right? If you’re familiar with flow, this is the code version of a Record Collection Variable for Accounts.

        for (Integer i = 0; i < 10; i++){

Now we start our For Loop. This says we’re going to create an integer variable of i, and we want i to equal zero. The i++ means we’re going to increment the value of i with every iteration of this code. So the first time we go through this code block (Lines 3 to 17), i = 0, the next time i = 1, etc. As long as i is less than 10, we’re going to keep iterating through this chunk of code. In Flow terms, we’re making a Loop, but we’re using a condition for our loop, rather than a collection that already exists.


            Account a = new Account(
                Name = 'Acme #' + i,
                Type = 'Prospect',
                BillingStreet = '415 Mission Street',
                BillingCity = 'San Francisco',
                BillingState = 'CA',
                BillingPostalCode = '94105',
                BillingCountry = 'USA'
            );


We’ll look at this next section together because it’s really one statement in our code. We’re creating a new variable to hold some Account data and we’re going to refer to that account as a. If you’re familiar with flow, this is the code version of a Record Variable for a single Account. Between the parenthesis, we’re setting field values. We went easy in this example and gave every account your favorite address and mine – the Salesforce Address. Be sure you’re setting all required fields your org has for Accounts (including Record Type if that’s important). If you need to differentiate anything, including the + i is a great way to append the loop iteration number to your values.

Note: If you have duplicate rules enabled, you’ll want to be sure you’re changing data enough to not trigger those rules. You’ll see I had added + i in line 5 to give my Accounts different names. I will expect 10 Accounts – Acme #0 through Acme #9


            if(i > 5){
                a.Industry = 'Education';
            }

Woah! This bit looks a little crazy doesn’t it? This is an if statement where we’re looking to see if we’re in iteration 6 …which is where i=5. Confusing, I know, but this how code works – ya start with 0. Again, if you think in terms of Flow, this is a decision element. This bit of code is only going to execute when i > 5. If i > 5, we want to set the Industry on the Account (remember above where we said we wanted an Account variable and we called it a?) This means that we should expect our first 5 Accounts to have no Industry value, and our last 5 Accounts to have an Industry of Education.


            accts.add(a);

This bit is easy, I promise! We’re going to refer to that list of Accounts from Line 1 – accts. And we’re going to use Dot Notation to say “Add the Account I just defined to the list”. In Flow terms, we’re adding our Single Record Variable to our Record Collection Variable.

        insert accts;

Time to drop the mic. We’re going to take that list of accounts we’ve been adding to, and insert it into the database.

Creating Contacts

This is where we create the Contacts. It is incredibly similar to how we created Accounts.

        List<Contact> cons = new List<Contact>();
        for (Account a : accts){
            for (Integer i = 0; i < 2; i++){
                Contact con = new Contact(
                    AccountId = a.Id,
                    FirstName = 'Test',
                    LastName = 'Smith ' + i
                );
                cons.add(c);
            }            
        }
        insert cons;

Disclaimer: Yes, there is a major loop violation here. We put a loop in a loop. But I couldn’t for the life of me figure out a better way to add more than one contact to my newly created Accounts. If you know a better way, let me know!

        List<Contact> cons = new List<Contact>();

Just like we did for Accounts, we’re creating a list of Contacts to use for our DML operations, and we want to call it cons. Flownatic Parallel: this is the code version of a Record Collection Variable for Contacts.

       for (Account a : accts){

We got creative with this bit (please refer to the earlier disclaimer). We want to cycle through all those accounts we just created, so we do that in line 22. We say we’re going to loop through Account records, we want to refer to each iteration as a, and we’re going to cycle through the list we already defined as accts. Flownatic Parallel: This is a Loop; accts is our Loop Collection and a is our Loop variable.

Note: I reused a as my variable here. That was a personal choice and your mileage may vary.

             for (Integer i = 0; i < 2; i++){

Just as we did for Accounts, we start our For Loop. This time though, we only want to iterate through twice – the first time, i = 0 and the second time i = 1, so we’ll stop when i = 2. Flownatic Parallel: A Loop, but we’re using a condition for our loop, rather than a collection that already exists.

                 Contact con = new Contact(
                    AccountId = a.Id,
                    FirstName = 'Test',
                    LastName = 'Smith ' + i
                );

Again, we’ll look at this next bit as one bit of code. We’re creating a new variable to hold some Contact data and we’re going to refer to that Contact as con. Flownatic Parallel: Single Record Variable for Contact. Between the parenthesis, we’re setting field values. The key this time is we’re using a.Id to set the AccountId field on the contact. Flownatic Parallel: An Assignment to set Contact Account Id to the Account Id variable. Remember to set all required fields your org has for Contacts (including Record Type if that’s important). If you need to differentiate anything, including the + i is a great way to append the loop iteration number to your values.

Remember: If you have duplicate rules enabled, you’ll want to be sure you’re changing data enough to not trigger those rules. You’ll see I had added + i to append the value of i to the Contact’s last name.

                cons.add(con);

Once more, we to refer to that list of Contacts we already declared in Line 21 – cons. And we’re going to add our newly defined Contact values to that list with our variable con. In Flow terms, we’re adding our Single Record Variable to our Record Collection Variable.

        insert cons;

And one last time, we insert into the database.

Making It Work For You

I’ll leave you with these final tips as things to remember to make it work for you:

  • Update variables so they’re meaningful to you
  • Any time you see the name of an object in this code, you should replace it with whatever object you need in your sandbox
    • List<Contact> cons = new List<Contact>();
      becomes
      List<Opportunity> opptys = new List<Opportunity>();
      to create a list for Opportunities
    • List<Contact> cons = new List<Contact>();
      becomes
      List<Sandwich__c> sammies = new List<Sandwich__c>();
      to create a list for a custom object of Sandwiches
    • Contact con = new Contact( AccountId = a.Id, FirstName = 'Test', LastName = 'Smith ');
      becomes
      Sandwich__c sandy = new Sandwich__c( Account__c = a.Id, Name = 'BLT', Side_1__c = 'Chips ');
      to create a custom object record of Sandwich
  • Always include required fields

Leave a comment