Simplified Approach To Apex Test Code Coverage

In Salesforce.com, Apex developers need to ensure the existence of 75% test code before deploying their code to a production environment. This requirement serves as a valuable measure ensuring that your code remains self-sufficient over time. Moreover, it automatically identifies any potential code-breaking changes within your orgs in the future.

Salesforce.com requires Apex coders to make sure 75%  test code exists before they can deploy their code to a production environment. That’s a very good thing because it ensures that your code can look after itself in years to come, and any changes in your orgs that may break your code will be flagged automatically.

When I was introduced to Apex it soon became obvious that there are many right and wrong ways to create your test code. I would like to share how I create the necessary data to run my test code, and also give you a free utility that will save you many hours of copying and pasting field names.

First, my top 2 testing tips:

  1. Create your own data / don’t base your test code on your org’s data!  Using the data which is currently in your org for running your tests is a very, very bad idea because anyone using your Org can make changes to this data which may break or invalidate your tests. Using existing data also won’t force you to consider exactly which data is required to execute your tests, something that creating your own test data will. There are some exceptions to this rule as for example you may have to use existing record types or a reference to the org’s standard price book but try to keep these exceptions to a minimum.
  2. Centralize your test data and make it available to all your classes and triggers.
    Nothing is more frustrating then someone changing a validation rule which breaks your test code which then results in you digging through all your code to figure out where you created the various objects before you can make the necessary changes to these fields so your test code passes these new validation rules. Whilst you can’t stop people adding validation rules, I always make sure that all my test data is created in one place so that it’s easier to find and update if needed.

So with the above in mind, here’s how I configure my test environment which I use for all my Apex projects:

Set up test utility

By installing the package in your Org and accessing the Visualforce page (e.g., …/apex/BuildTestDataObject), you’ll streamline the process of generating Apex test code. This utility eliminates the time-consuming task of copying and pasting field names. Simply select the desired SObject on the page, and it will automatically generate the relevant Apex test code for you. With this generated Apex code, your task will be to uncomment the fields you intend to populate and strategically position commas so that each uncommented field, except the last one, is appropriately separated. This tool can significantly reduce the time spent on data preparation.

Create a new UnitTestDataFactory class

This class will contain public variables and declarations of test data. The following is an abridged example of how I create Product test data in this class. This class would normally contain many more objects:

public with sharing class UnitTestDataFactory {

		public static 	Product2 varProduct2;	// See note 1

		public static	Product2 createProduct2() // See note 2
		{
			return new Product2(
				// NumberOfQuantityInstallments	= '',
				// Code_1__c					= '',
				// SIS_ID__c					= '',
				// MPower_weblink__c			= '',
				// Estimated_life_time__c		= '',
				// Item_Group_Description__c	= '',
				// CreatedById					= '',
				// LastModifiedDate				= '',
				// Id							= '',
				// IsActive						= '',
				Description						= 'Test Product'
				// Family						= '',
				// Name							= '',
				// IsDeleted					= '',
				// RecordTypeId					= '',
				// Item_Group__c				= '',
				// SystemModstamp				= '',
				// QuantityInstallmentPeriod	= '',
				// ProductCode					= '',
				// Product_Family__c			= '',
				// CreatedDate					= '',
				// CanUseQuantitySchedule		= '',
				// Part_Image__c				= '',
				// ImageID__c					= '',
				// QuantityScheduleType			= '',
				// Business_Unit__c				= '',
				// ITNO__c						= '',
				// Code_0__c					= '',
				// Item_Number__c				= '',
				// LastModifiedById				= '',
				// CurrencyIsoCode				= '',
				// Product_Group_Code__c		= ''
			);
		}

		public	static void	CreateTestData()		// See note 3
		{

			//	See note 4

			varProduct2= UnitTestDataFactory.createProduct2();
			insert	varProduct2;
			System.assertNotEqual(varProduct2.Id,null,’Failed to create Product2’);

		}

	}

Notes to the above code:

  • I declare a global object which I can refer to from outside this class
  • The createProduct2 method is generated automatically  by the test utility and the only things I had to do manually were
    • Copy the code into my test class
    • Remove the // in front of the only field I want to populate (Description)
    • Populate that field with my desired value (‘Test Product’)
    • Remove the , from the end of that line so the structure is formatted correctly.
  • The CreateTestData method will be called from all my external classes and triggers to create all the objects I need
  • In the CreateTestData method I:
    • Populate my global varProduct2 variable using the createProduct2 method
    • Insert variable into my test environment
    • Use an assert statement to make sure the insert worked correctly and report a meaningful error if it didn’t

Add test code to my classes and triggers

With the above UnitTestDataFactory in place, I will now reference this data in all my classes and triggers by simply adding the code below to all these individual files:

static void testMethods(){

		Test.startTest();

    	//	Create data objects

    	UnitTestDataFactory.CreateTestData();	 //	Create data object

		//	And now add your additional test logic
	}

Your test data is prepared and available for utilization. Simply utilize the packaged utility to include all necessary objects into the UnitTestDataFactory. Ensure that you create them in the correct sequence. You’ll notice that establishing centralized test data becomes notably simpler and faster.