Trapdoor In The Sun

Alan Shanahan, Technician & Consultant


1 Comment

Force.com Apex Test Assertions: It Must Be a Real Test

In the course of building automated tests, it’s always good practice to pepper your test code with Assert statements to ensure your code is functioning as you would expect throughout. But, as I’ve seen more than one example of the specific behaviour in the first code section below, I think it’s something I should point out.

On first glance, it looks like the assertion is doing the right thing. But if you think about it, it’s not a real test. It only tests that the in-memory variable testAcc.Name has the value originally assigned to it a couple of lines back.

// Example 1. An in-memory-based test
Account testAcc = new Account();
testAcc.Name = 'Testing 123';
insert testAcc;

System.assertEquals('Testing123',testAcc.Name);

What it really needs to do, so that it becomes a “real” test is for the test method to query the database record just inserted and to retrieve the Name value from the record, then check it against the expected value, as shown below.

// Example 2. A database-based test
Account testAcc = new Account();
testAcc.Name = 'Testing 123';
insert testAcc;

Account checkAcc = [SELECT Name FROM Account WHERE Id = :testAcc.Id];
System.assertEquals(checkAcc.Name,testAcc.Name);

This example is, perhaps, not a great real-world scenario but I feel it illustrates the problem well.

Happy coding, if it’s your thing.


Leave a comment

Force.com: Build Your Own Test Data Creation Suite

Every coded Force.com project needs its unit test suite. The platform has recently adapted its default practice to make it impossible for your test code to see any data in the database, BUT this is a good thing: it forces us to create unit tests that are truly data-independent. This makes them more portable, and safer.

Another practice that is highly recommended and advantageous to adopt is that of “writing once, reusing many times”; as is true for all code. What I’ve done here is to create a generic template that will help you create test data as you need it, from a common library of methods that are adaptable and can be reused. And the paradigm stretches to include bulk creation of data, which is necessary in the constrained world of Apex programming.

This post gives you the ability to add code to your project that will allow you to create, with very little additional effort, a full set of test data for your own methods and classes to play with. And I won’t be holding back; in fact, by the end of this post you will have a fully-described body of code that you can use as the starting point for your own project.

To demonstrate the concept, I’ve created a set of data-creation methods that will generate data for 4 standard Force.com objects: Account, Contact, Opportunity and OpportunityContactRole. Anyone familiar with the SFA application will understand what these objects are and how they are related. It’s important to understand the links between these tables, however:

  • Account is a top-level or parent table.
  • Contact is a child object of Account. There can be zero or more Contact records related to an Account.
  • Opportunity is a child object of Account. There can be zero or more Opportunity records related to an Account.
  • The OpportunityContactRole object is a “junction object”; it links two tables, in this case Contact and Opportunity. It can also store an optional Role for each record.

This link will show you an entity relationship diagram (ERD) that may help to clarify. Note, also, that I use the terms “object” and “table” interchangeably. For the purposes of this blog post, it will not be necessary to make any distinction and you can think of them as the same thing.

I’ll walk you through the code now. There will be links to the full class and its own test class at the end of the post.

First, we define the class and provide some high-level comments.

public class MyTestDataSuite {
	//================================================================================
	// This class contains a basic blueprint for a generic test data creation suite.
	// Clone and adapt the samples for your own custom objects and fields.
	// Ensure you complement the suite with comprehensive unit tests.
	//================================================================================

Below, I’ve defined some text constants used for the creation of test data. I’ve tried to use some data that is not likely to exist in the database, but as long as you’re not using the IsTest(SeeAllData=true) annotation and are using version 24 of the API or higher, there will be no conflict with existing data. Click here for more information.

	//--------------------------------------------------------------------------------
	// Definition of constants
	//--------------------------------------------------------------------------------
	public static final String ACCOUNT_NAME_PREFIX     = 'TEST ACCOUNT XXXX';
	public static final String CONTACT_NAME_PREFIX1    = 'FIRSTZZZZ';
	public static final String CONTACT_NAME_PREFIX2    = 'LASTZZZZ';
	public static final String OPPORTUNITY_NAME_PREFIX = 'OPPTYZZZZ';

	public static final String CONTACT_SIZE_MISMATCH =
		'Class/Method MyTestDataSuite/createTestContactData:' +
		' Number of Contact records requested does not match related Account map size.';
	public static final String OPPORTUNITY_SIZE_MISMATCH =
		'Class/Method MyTestDataSuite/createTestOpportunityData:' +
		' Number of Opportunity records requested does not match related Account map size.';
	public static final String OCR_SIZE_MISMATCH1 =
		'Class/Method MyTestDataSuite/createTestOCRData:' +
		' Number of OpportunityContactRole records requested does not match related Opportunity map size.';
	public static final String OCR_SIZE_MISMATCH2 =
		'Class/Method MyTestDataSuite/createTestOCRData:' +
		' Number of OpportunityContactRole records requested does not match related Contact map size.';

In the next short section, I’ve simply defined an Exception class to be used by the data creation methods, primarily where unrecoverable errors occur.

	//--------------------------------------------------------------------------------
	// Internal Exception class
	//--------------------------------------------------------------------------------
	public class DataSuiteException extends Exception {}

Just below, we’re finally getting into the real meat of the post. After the initial bounds checking, this code iterates through an integer loop, creating an Account record with incrementing names; they are then added to the return map, using the integer as a map key.

	//--------------------------------------------------------------------------------
	// This is where the batch of Account records are created.
	//--------------------------------------------------------------------------------
	public static Map<Integer,Account> createTestAccountData(Integer numAccs) {

		// Carry out some batch size bounds checking
		if (numAccs > 200) numAccs = 200;
		if (numAccs < 0)   numAccs = 0;

		// Initialise any initial, incrementing or unique values here
		String  wrkAccNamePrefix = ACCOUNT_NAME_PREFIX;
		Integer wrkAccountNumber = 200001;

		// Create the requested number of Account records
        Map<Integer,Account> wrkMapAccs = new Map<Integer,Account>();
        for (Integer iX = 1; iX<=numAccs; iX++) {
			Account wrkAcc = createTestAccountRecord(
				 wrkAccountNumber
				,wrkAccNamePrefix
			);
			wrkMapAccs.put(iX,wrkAcc);
			wrkAccountNumber++;
        }
		return wrkMapAccs;
    }

It’s important to note that I’ve broken out the creation of each individual record into a method in its own right. This makes it easier to read, and easier to maintain. If you wish to populate the values of any other object fields, this is the place to do it.

	//--------------------------------------------------------------------------------
	// Creation of each Account record takes place here
	//--------------------------------------------------------------------------------
	static Account createTestAccountRecord(Integer accNum, String accPfx) {

		Account wrkAccount = new Account(
			 Name                     = accPfx + ' ' + String.valueOf(accNum)
			,Custom_Account_Number__c = accNum
		);
		return wrkAccount;

	}

Below, I’ve created a similar data creation method for Contact, but note the addition of the mapInt2Account map structure; this allows the Contact to be linked to its parent Account record (on a 1:1 basis), by populating the AccountId lookup field with the parent Id value. The bounds checking is a little more involved here; I’m checking that the request to create N Contact records is accompanied by N Account (parent) records to “attach” them to.

 	//--------------------------------------------------------------------------------
	// This is where the batch of Contact records are created.
	//--------------------------------------------------------------------------------
	 public static Map<Integer,Contact> createTestContactData(Integer numCons, Map<Integer,Account> mapInt2Account) {

		// Carry out some batch size bounds checking
		if (numCons > 200) numCons = 200;
		if (numCons < 0)   numCons = 0;
		if (numCons != mapInt2Account.size()) {
			throw new MyTestDataSuite.DataSuiteException(CONTACT_SIZE_MISMATCH);
		}

		// Initialise any initial, incrementing or unique values here
		String  wrkConNamePrefix1 = CONTACT_NAME_PREFIX1;
		String  wrkConNamePrefix2 = CONTACT_NAME_PREFIX2;
		Integer wrkContactNumber  = 200001;

		// Create the requested number of Contact records
        Map<Integer,Contact> wrkMapCons = new Map<Integer,Contact>();
        for (Integer iX = 1; iX<=numCons; iX++) {
			Contact wrkCon = createTestContactRecord(
				 wrkContactNumber
				,mapInt2Account.get(iX).Id
				,wrkConNamePrefix1
				,wrkConNamePrefix2
			);
			wrkMapCons.put(iX,wrkCon);
			wrkContactNumber++;
        }
		return wrkMapCons;
    }

	//--------------------------------------------------------------------------------
	// Creation of each Contact record takes place here
	//--------------------------------------------------------------------------------
	static Contact createTestContactRecord(Integer conNum, Id accId, String conPfx1, String conPfx2) {

		Contact wrkContact = new Contact(
			 AccountId     = accId
			,FirstName     = conPfx1 + ' ' + String.valueOf(conNum)
			,LastName      = conPfx2 + ' ' + String.valueOf(conNum)
		);
		return wrkContact;

	}

The creation of Opportunity records is similar to that of Contacts, with it being related to the Account object by way of a lookup field.

 	//--------------------------------------------------------------------------------
	// This is where the batch of Opportunity records are created.
	//--------------------------------------------------------------------------------
	 public static Map<Integer,Opportunity> createTestOpportunityData(
	 	 Integer numOpps
	 	,Map<Integer,Account> mapInt2Account
	 	,String strStageName
	 	,Date datCloseDate
	 ) {

		// Carry out some batch size bounds checking
		if (numOpps > 200) numOpps = 200;
		if (numOpps < 0)   numOpps = 0;
		if (numOpps != mapInt2Account.size()) {
			throw new MyTestDataSuite.DataSuiteException(OPPORTUNITY_SIZE_MISMATCH);
		}

		// Initialise any initial, incrementing or unique values here
		String  wrkOppNamePrefix     = OPPORTUNITY_NAME_PREFIX;
		Integer wrkOpportunityNumber = 200001;

		// Create the requested number of Opportunity records
        Map<Integer,Opportunity> wrkMapOpps = new Map<Integer,Opportunity>();
        for (Integer iX = 1; iX<=numOpps; iX++) {
			Opportunity wrkOpp = createTestOpportunityRecord(
				 wrkOpportunityNumber
				,mapInt2Account.get(iX).Id
				,wrkOppNamePrefix
				,strStageName
				,datCloseDate
			);
			wrkMapOpps.put(iX,wrkOpp);
			wrkOpportunityNumber++;
        }
		return wrkMapOpps;
    }

	//--------------------------------------------------------------------------------
	// Creation of each Opportunity record takes place here
	//--------------------------------------------------------------------------------
	static Opportunity createTestOpportunityRecord(Integer oppNum, Id accId, String oppPfx, String stageName, Date closeDate) {

		Opportunity wrkOpportunity = new Opportunity(
			 AccountId     = accId
			,Name          = oppPfx + ' ' + String.valueOf(oppNum)
			,StageName     = stageName
			,CloseDate     = closeDate
		);
		return wrkOpportunity;

	}

The creation of OpportunityContactRole records, below, is simple, in that there are only a small number of fields to be populated for this to make any sense. But it’s slight more tricky because it needs to be aware of both the Contact and Opportunity maps created earlier. It’s all about dependencies and ensuring they are maintained correctly.

 	//--------------------------------------------------------------------------------
	// This is where the batch of Opportunity Contact Role records are created.
	//--------------------------------------------------------------------------------
	 public static Map<Integer,OpportunityContactRole> createTestOCRData(
	 	 Integer numOCRs
	 	,Map<Integer,Opportunity> mapInt2Opportunity
	 	,Map<Integer,Contact> mapInt2Contact
	 	,String strRole
	 ) {

		// Carry out some batch size bounds checking
		if (numOCRs > 200) numOCRs = 200;
		if (numOCRs < 0)   numOCRs = 0;
		if (numOCRs != mapInt2Opportunity.size()) {
			throw new MyTestDataSuite.DataSuiteException(OCR_SIZE_MISMATCH1);
		}
		if (numOCRs != mapInt2Contact.size()) {
			throw new MyTestDataSuite.DataSuiteException(OCR_SIZE_MISMATCH2);
		}

		// Initialise any initial, incrementing or unique values here (commented lines, below, left in for clarity)
		//String  wrkOCRNamePrefix     = 'OPPTYZZZZ';
		//Integer wrkOCRNumber         = 200001;

		// Create the requested number of OpportunityContactRole records
        Map<Integer,OpportunityContactRole> wrkMapOCRs = new Map<Integer,OpportunityContactRole>();
        for (Integer iX = 1; iX<=numOCRs; iX++) {
			OpportunityContactRole wrkOCR = createTestOCRRecord(
				 mapInt2Contact.get(iX).Id
				,mapInt2Opportunity.get(iX).Id
				,strRole
			);
			wrkMapOCRs.put(iX,wrkOCR);
			//wrkOCRNumber++;
        }
		return wrkMapOCRs;
    }

Here, you can see that there are two ID fields to be populated. The Role and IsPrimary fields are optional, so make whatever changes are appropriate to your needs here.

	//--------------------------------------------------------------------------------
	// Creation of each OpportunityContactRole record takes place here
	//--------------------------------------------------------------------------------
	static OpportunityContactRole createTestOCRRecord(Id conId, Id oppId, String ocrRole) {

		OpportunityContactRole wrkOCR = new OpportunityContactRole(
			 ContactId     = conId
			,OpportunityId = oppId
			,Role          = ocrRole
			,IsPrimary     = TRUE
		);
		return wrkOCR;

	}

The class wouldn’t be complete without a closing backet.

}

I’ve included the full source code for the above class here, along with its test class. I don’t claim the test class is complete; you may wish to consider adding some more unit tests to make it complete, especially around edge test cases.

The full MyTestDataSuite class:

public class MyTestDataSuite {
	//================================================================================
	// This class contains a basic blueprint for a generic test data creation suite.
	// Clone and adapt the samples for your own custom objects and fields.
	// Ensure you complement the suite with comprehensive unit tests.
	//================================================================================

	//--------------------------------------------------------------------------------
	// Definition of constants
	//--------------------------------------------------------------------------------
	public static final String ACCOUNT_NAME_PREFIX     = 'TEST ACCOUNT XXXX';
	public static final String CONTACT_NAME_PREFIX1    = 'FIRSTZZZZ';
	public static final String CONTACT_NAME_PREFIX2    = 'LASTZZZZ';
	public static final String OPPORTUNITY_NAME_PREFIX = 'OPPTYZZZZ';

	public static final String CONTACT_SIZE_MISMATCH =
		'Class/Method MyTestDataSuite/createTestContactData:' +
		' Number of Contact records requested does not match related Account map size.';
	public static final String OPPORTUNITY_SIZE_MISMATCH =
		'Class/Method MyTestDataSuite/createTestOpportunityData:' +
		' Number of Opportunity records requested does not match related Account map size.';
	public static final String OCR_SIZE_MISMATCH1 =
		'Class/Method MyTestDataSuite/createTestOCRData:' +
		' Number of OpportunityContactRole records requested does not match related Opportunity map size.';
	public static final String OCR_SIZE_MISMATCH2 =
		'Class/Method MyTestDataSuite/createTestOCRData:' +
		' Number of OpportunityContactRole records requested does not match related Contact map size.';
	
	//--------------------------------------------------------------------------------
	// Internal Exception class
	//--------------------------------------------------------------------------------
	public class DataSuiteException extends Exception {}


	//--------------------------------------------------------------------------------
	// This is where the batch of Account records are created.
	//--------------------------------------------------------------------------------
	public static Map<Integer,Account> createTestAccountData(Integer numAccs) {

		// Carry out some batch size bounds checking
		if (numAccs > 200) numAccs = 200;
		if (numAccs < 0)   numAccs = 0;

		// Initialise any initial, incrementing or unique values here
		String  wrkAccNamePrefix = ACCOUNT_NAME_PREFIX;
		Integer wrkAccountNumber = 200001;

		// Create the requested number of Account records
        Map<Integer,Account> wrkMapAccs = new Map<Integer,Account>();
        for (Integer iX = 1; iX<=numAccs; iX++) {
			Account wrkAcc = createTestAccountRecord(
				 wrkAccountNumber
				,wrkAccNamePrefix
			);
			wrkMapAccs.put(iX,wrkAcc);
			wrkAccountNumber++;
        }
		return wrkMapAccs;
    }
                                                         

	//--------------------------------------------------------------------------------
	// Creation of each Account record takes place here
	//--------------------------------------------------------------------------------
	static Account createTestAccountRecord(Integer accNum, String accPfx) {

		Account wrkAccount = new Account(
			 Name                     = accPfx + ' ' + String.valueOf(accNum)
			,Custom_Account_Number__c = accNum
		);
		return wrkAccount;

	}

    
 	//--------------------------------------------------------------------------------
	// This is where the batch of Contact records are created.
	//--------------------------------------------------------------------------------
	 public static Map<Integer,Contact> createTestContactData(Integer numCons, Map<Integer,Account> mapInt2Account) {

		// Carry out some batch size bounds checking
		if (numCons > 200) numCons = 200;
		if (numCons < 0)   numCons = 0;
		if (numCons != mapInt2Account.size()) {
			throw new MyTestDataSuite.DataSuiteException(CONTACT_SIZE_MISMATCH);
		}

		// Initialise any initial, incrementing or unique values here
		String  wrkConNamePrefix1 = CONTACT_NAME_PREFIX1;
		String  wrkConNamePrefix2 = CONTACT_NAME_PREFIX2;
		Integer wrkContactNumber  = 200001;

		// Create the requested number of Contact records
        Map<Integer,Contact> wrkMapCons = new Map<Integer,Contact>();
        for (Integer iX = 1; iX<=numCons; iX++) {
			Contact wrkCon = createTestContactRecord(
				 wrkContactNumber
				,mapInt2Account.get(iX).Id
				,wrkConNamePrefix1
				,wrkConNamePrefix2
			);
			wrkMapCons.put(iX,wrkCon);
			wrkContactNumber++;
        }
		return wrkMapCons;
    }
                                                         

	//--------------------------------------------------------------------------------
	// Creation of each Contact record takes place here
	//--------------------------------------------------------------------------------
	static Contact createTestContactRecord(Integer conNum, Id accId, String conPfx1, String conPfx2) {

		Contact wrkContact = new Contact(
			 AccountId     = accId
			,FirstName     = conPfx1 + ' ' + String.valueOf(conNum)
			,LastName      = conPfx2 + ' ' + String.valueOf(conNum)
		);
		return wrkContact;

	}
    
    
 	//--------------------------------------------------------------------------------
	// This is where the batch of Opportunity records are created.
	//--------------------------------------------------------------------------------
	 public static Map<Integer,Opportunity> createTestOpportunityData(
	 	 Integer numOpps
	 	,Map<Integer,Account> mapInt2Account
	 	,String strStageName
	 	,Date datCloseDate
	 ) {

		// Carry out some batch size bounds checking
		if (numOpps > 200) numOpps = 200;
		if (numOpps < 0)   numOpps = 0;
		if (numOpps != mapInt2Account.size()) {
			throw new MyTestDataSuite.DataSuiteException(OPPORTUNITY_SIZE_MISMATCH);
		}

		// Initialise any initial, incrementing or unique values here
		String  wrkOppNamePrefix     = OPPORTUNITY_NAME_PREFIX;
		Integer wrkOpportunityNumber = 200001;

		// Create the requested number of Opportunity records
        Map<Integer,Opportunity> wrkMapOpps = new Map<Integer,Opportunity>();
        for (Integer iX = 1; iX<=numOpps; iX++) {
			Opportunity wrkOpp = createTestOpportunityRecord(
				 wrkOpportunityNumber
				,mapInt2Account.get(iX).Id
				,wrkOppNamePrefix
				,strStageName
				,datCloseDate
			);
			wrkMapOpps.put(iX,wrkOpp);
			wrkOpportunityNumber++;
        }
		return wrkMapOpps;
    }
                                                         

	//--------------------------------------------------------------------------------
	// Creation of each Opportunity record takes place here
	//--------------------------------------------------------------------------------
	static Opportunity createTestOpportunityRecord(Integer oppNum, Id accId, String oppPfx, String stageName, Date closeDate) {

		Opportunity wrkOpportunity = new Opportunity(
			 AccountId     = accId
			,Name          = oppPfx + ' ' + String.valueOf(oppNum)
			,StageName     = stageName
			,CloseDate     = closeDate
		);
		return wrkOpportunity;

	}
    
    
 	//--------------------------------------------------------------------------------
	// This is where the batch of Opportunity Contact Role records are created.
	//--------------------------------------------------------------------------------
	 public static Map<Integer,OpportunityContactRole> createTestOCRData(
	 	 Integer numOCRs
	 	,Map<Integer,Opportunity> mapInt2Opportunity
	 	,Map<Integer,Contact> mapInt2Contact
	 	,String strRole
	 ) {

		// Carry out some batch size bounds checking
		if (numOCRs > 200) numOCRs = 200;
		if (numOCRs < 0)   numOCRs = 0;
		if (numOCRs != mapInt2Opportunity.size()) {
			throw new MyTestDataSuite.DataSuiteException(OCR_SIZE_MISMATCH1);
		}
		if (numOCRs != mapInt2Contact.size()) {
			throw new MyTestDataSuite.DataSuiteException(OCR_SIZE_MISMATCH2);
		}

		// Initialise any initial, incrementing or unique values here (commented lines, below, left in for clarity)
		//String  wrkOCRNamePrefix     = 'OPPTYZZZZ';
		//Integer wrkOCRNumber         = 200001;

		// Create the requested number of OpportunityContactRole records
        Map<Integer,OpportunityContactRole> wrkMapOCRs = new Map<Integer,OpportunityContactRole>();
        for (Integer iX = 1; iX<=numOCRs; iX++) {
			OpportunityContactRole wrkOCR = createTestOCRRecord(
				 mapInt2Contact.get(iX).Id
				,mapInt2Opportunity.get(iX).Id
				,strRole
			);
			wrkMapOCRs.put(iX,wrkOCR);
			//wrkOCRNumber++;
        }
		return wrkMapOCRs;
    }
                                                         

	//--------------------------------------------------------------------------------
	// Creation of each OpportunityContactRole record takes place here
	//--------------------------------------------------------------------------------
	static OpportunityContactRole createTestOCRRecord(Id conId, Id oppId, String ocrRole) {

		OpportunityContactRole wrkOCR = new OpportunityContactRole(
			 ContactId     = conId
			,OpportunityId = oppId
			,Role          = ocrRole
			,IsPrimary     = TRUE
		);
		return wrkOCR;

	}
    
    
     
}

The full MyTestDataSuiteTEST class:

@isTest
private class MyTestDataSuiteTEST {

	//--------------------------------------------------------------------------------
	// Test method for Account batch creation
	//                 Contact batch creation
	//                 Opportunity batch creation
	//                 OpportunityContactRole batch creation
	//--------------------------------------------------------------------------------
    static testMethod void createAccConOppOCR() {

		// Specify the start of a test data creation session
		Test.startTest();

		// Create map of Account records
		Map<Integer,Account> mapInt2Account =
			MyTestDataSuite.createTestAccountData(200);
		insert mapInt2Account.values();

		// Create map of Contact records
		Map<Integer,Contact> mapInt2Contact =
			MyTestDataSuite.createTestContactData(200, mapInt2Account);
		insert mapInt2Contact.values();

		// Create map of Opportunity records
		Map<Integer,Opportunity> mapInt2Opportunity =
			MyTestDataSuite.createTestOpportunityData(200, mapInt2Account, 'Closed Won', System.Today());
		insert mapInt2Opportunity.values();

		// Create map of OpportunityContactRole records
		Map<Integer,OpportunityContactRole> mapInt2OCR =
			MyTestDataSuite.createTestOCRData(200, mapInt2Opportunity, mapInt2Contact, 'Business User');
		insert mapInt2OCR.values();

		// Verify that the right number of map elements have been created
		System.AssertEquals(200,mapInt2Account.size());
		System.AssertEquals(200,mapInt2Contact.size());
		System.AssertEquals(200,mapInt2Opportunity.size());
		System.AssertEquals(200,mapInt2OCR.size());

		// Randomly check that the variable elements of the Account map were created as expected
		System.AssertEquals(MyTestDataSuite.ACCOUNT_NAME_PREFIX + ' ' + '200001', mapInt2Account.get(  1).Name);
		System.AssertEquals(MyTestDataSuite.ACCOUNT_NAME_PREFIX + ' ' + '200033', mapInt2Account.get( 33).Name);
		System.AssertEquals(MyTestDataSuite.ACCOUNT_NAME_PREFIX + ' ' + '200107', mapInt2Account.get(107).Name);
		System.AssertEquals(MyTestDataSuite.ACCOUNT_NAME_PREFIX + ' ' + '200200', mapInt2Account.get(200).Name);

		// Retrieve random set of Contact records from database and check Name concatenation
		List<String> lstFirstNames = new List<String>();
		lstFirstNames.add(MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200001');
		lstFirstNames.add(MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200015');
		lstFirstNames.add(MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200131');
		lstFirstNames.add(MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200200');
		List<Contact> lstContact1 = [
			SELECT Id, Name, FirstName, LastName
			FROM Contact
			WHERE FirstName IN :lstFirstNames
		];
		System.AssertEquals(4, lstContact1.size());  // Ensure we have retrieved 4 records from database

		Integer conCount1 = 0;  // Counter for verified Contact records
		for (Contact iCon : lstContact1) {
			if (iCon.FirstName == MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200001') {  // Check Contact record 1
				conCount1++;
				System.AssertEquals(iCon.Name,MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200001' + ' ' +
				                              MyTestDataSuite.CONTACT_NAME_PREFIX2 + ' ' + '200001');
			}
			if (iCon.FirstName == MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200015') {  // Check Contact record 2
				conCount1++;
				System.AssertEquals(iCon.Name,MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200015' + ' ' +
				                              MyTestDataSuite.CONTACT_NAME_PREFIX2 + ' ' + '200015');
			}
			if (iCon.FirstName == MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200131') {  // Check Contact record 3
				conCount1++;
				System.AssertEquals(iCon.Name,MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200131' + ' ' +
				                              MyTestDataSuite.CONTACT_NAME_PREFIX2 + ' ' + '200131');
			}
			if (iCon.FirstName == MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200200') {  // Check Contact record 4
				conCount1++;
				System.AssertEquals(iCon.Name,MyTestDataSuite.CONTACT_NAME_PREFIX1 + ' ' + '200200' + ' ' +
				                              MyTestDataSuite.CONTACT_NAME_PREFIX2 + ' ' + '200200');
			}
		}
		System.AssertEquals(4,conCount1);  // There should be 4 verified Contact records




		// Specify the end of a test data creation session
		Test.stopTest();

    }


	//--------------------------------------------------------------------------------
	// Test method for Account & Contact batch creation bounds checking
	//--------------------------------------------------------------------------------
    static testMethod void createAccountBoundsCheck() {

		// Specify the start of a test data creation session
		Test.startTest();

		// ACCOUNT

		// Create map of Account records with -3 elements (0 will be created)
		Map<Integer,Account> mapInt2AccountA =
			MyTestDataSuite.createTestAccountData(-3);
		System.AssertEquals(0, mapInt2AccountA.size());

		// Create map of Account records with 5000 elements (200 will be created)
		Map<Integer,Account> mapInt2AccountB =
			MyTestDataSuite.createTestAccountData(5000);
		System.AssertEquals(200, mapInt2AccountB.size());

		// Specify the end of a test data creation session
		Test.stopTest();

    }

    static testMethod void createContactBoundsCheck() {

		// Specify the start of a test data creation session
		Test.startTest();

		// CONTACT

		// Create map of Account records with 200 elements
		Map<Integer,Account> mapInt2AccountA =
			MyTestDataSuite.createTestAccountData(200);
		System.AssertEquals(200, mapInt2AccountA.size());

		// Create map of Contact records with 1234 elements (200 will be created)
		Map<Integer,Contact> mapInt2ContactA =
			MyTestDataSuite.createTestContactData(1234, mapInt2AccountA);
		System.AssertEquals(200, mapInt2ContactA.size());

		// Create map of Contact records with 10 elements (from 200 Account, exception will be thrown)
		try {
			Map<Integer,Contact> mapInt2ContactB =
				MyTestDataSuite.createTestContactData(10, mapInt2AccountA);
			System.Assert(false);  // This line should not be reached.
		}
		catch (Exception ex1) {
			System.Assert(ex1 instanceOf MyTestDataSuite.DataSuiteException);
			System.AssertEquals(ex1.getMessage(),MyTestDataSuite.CONTACT_SIZE_MISMATCH);
		}

		// Specify the end of a test data creation session
		Test.stopTest();

    }

    static testMethod void createOpportunityBoundsCheck() {

		// Specify the start of a test data creation session
		Test.startTest();

		// OPPORTUNITY

		// Create map of Account records with 200 elements
		Map<Integer,Account> mapInt2AccountA =
			MyTestDataSuite.createTestAccountData(200);
		System.AssertEquals(200, mapInt2AccountA.size());

		// Create map of Opportunity records with 201 elements (200 will be created)
		Map<Integer,Opportunity> mapInt2OpportunityA =
			MyTestDataSuite.createTestOpportunityData(201, mapInt2AccountA, 'Closed Won', System.Today());
		System.AssertEquals(200, mapInt2OpportunityA.size());

		// Create map of Opportunity records with 199 elements (from 200 Accounts, exception will be thrown)
		try {
			Map<Integer,Opportunity> mapInt2OpportunityB =
				MyTestDataSuite.createTestOpportunityData(199, mapInt2AccountA, 'Closed Won', System.Today());
			System.Assert(false);  // This line should not be reached.
		}
		catch (Exception ex1) {
			System.Assert(ex1 instanceOf MyTestDataSuite.DataSuiteException);
			System.AssertEquals(ex1.getMessage(),MyTestDataSuite.OPPORTUNITY_SIZE_MISMATCH);
		}

		// Specify the end of a test data creation session
		Test.stopTest();

    }

    static testMethod void createOCRBoundsCheck() {

		// Specify the start of a test data creation session
		Test.startTest();

		// OPPORTUNITYCONTACTROLE

		// Create map of Account records with 200 elements
		Map<Integer,Account> mapInt2AccountA =
			MyTestDataSuite.createTestAccountData(200);
		System.AssertEquals(200, mapInt2AccountA.size());

		// Create map of Account records with 100 elements
		Map<Integer,Account> mapInt2AccountB =
			MyTestDataSuite.createTestAccountData(100);
		System.AssertEquals(100, mapInt2AccountB.size());

		// Create map of Contact records with 200 elements
		Map<Integer,Contact> mapInt2ContactA =
			MyTestDataSuite.createTestContactData(200, mapInt2AccountA);
		System.AssertEquals(200, mapInt2ContactA.size());

		// Create map of Contact records with 100 elements
		Map<Integer,Contact> mapInt2ContactB =
			MyTestDataSuite.createTestContactData(100, mapInt2AccountB);
		System.AssertEquals(100, mapInt2ContactB.size());

		// Create map of Opportunity records with 200 elements
		Map<Integer,Opportunity> mapInt2OpportunityA =
			MyTestDataSuite.createTestOpportunityData(200, mapInt2AccountA, 'Closed Won', System.Today());
		System.AssertEquals(200, mapInt2OpportunityA.size());

		// Create map of Opportunity records with 100 elements
		Map<Integer,Opportunity> mapInt2OpportunityB =
			MyTestDataSuite.createTestOpportunityData(100, mapInt2AccountB, 'Closed Won', System.Today());
		System.AssertEquals(100, mapInt2OpportunityB.size());

		// Create map of OpportunityContactRole records with 200 elements
		Map<Integer,OpportunityContactRole> mapInt2OCRA =
			MyTestDataSuite.createTestOCRData(200, mapInt2OpportunityA, mapInt2ContactA, 'Business User');
		System.AssertEquals(200, mapInt2OCRA.size());

		// Create map of OpportunityContactRole records with 123 elements (from 100 Opportunity records, exception will be thrown)
		try {
			Map<Integer,OpportunityContactRole> mapInt2OCRB =
				MyTestDataSuite.createTestOCRData(123, mapInt2OpportunityB, mapInt2ContactA, 'Business User');
			System.Assert(false);  // This line should not be reached.
		}
		catch (Exception ex1) {
			System.Assert(ex1 instanceOf MyTestDataSuite.DataSuiteException);
			System.AssertEquals(ex1.getMessage(),MyTestDataSuite.OCR_SIZE_MISMATCH1);
		}

		// Create map of OpportunityContactRole records with 100 elements (from 200 Contact records, exception will be thrown)
		try {
			Map<Integer,OpportunityContactRole> mapInt2OCRC =
				MyTestDataSuite.createTestOCRData(100, mapInt2OpportunityB, mapInt2ContactA, 'Business User');
			System.Assert(false);  // This line should not be reached.
		}
		catch (Exception ex1) {
			System.Assert(ex1 instanceOf MyTestDataSuite.DataSuiteException);
			System.AssertEquals(ex1.getMessage(),MyTestDataSuite.OCR_SIZE_MISMATCH2);
		}

		// Specify the end of a test data creation session
		Test.stopTest();

    }


}

I will leave it to you to attempt to decipher the code in the test class. If there is sufficient demand, I’ll add a post with a descriptive walkthrough. All comments are welcome and encouraged.