Apex Test Code Coverage Done the Easy Way

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:

Install test utility

I’ve created an unmanaged package containing a Visual Force page and Apex controller which will save you many hours to copying and pasting field names. Install the package on your  Org and then invoke the Visualforce page (i.e. …/apex/BuildTestDataObject). On that page, select the SObject for which you want to create a test data record and it will generate the appropriate Apex test code for you. The only thing you need to do with this Apex code is to un-comment the fields you actually want to populate and strategically place the commas so that every un-commented field except the last one has one.

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:

      1. I declare a global object which I can refer to from outside this class
      2. 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.
      3. The CreateTestData method will be called from all my external classes and triggers to create all the objects I need
      4. 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 now ready for use. Just add all the objects you require to the UnitTestDataFactory using the packaged utility, making sure that you create them in the right order and you’ll find that creating centralized test data suddenly becomes easier and quicker.

Happy testing!

Published
March 19, 2013
Topics:

Leave your comments...

Apex Test Code Coverage Done the Easy Way