Professional Documents
Culture Documents
Test Classes
Test Classes
=============
Upon implementing the application features, we are preparing a collection of
Business Logic Functionalities in the form of "Apex Classes, Triggers, Batch
Classes, Schedule Classes, VF Controller Classes, WebServices and API's".
We can test the features by preparing the Automated Scripts by using Apex
Programming which are called as "Test Classes".
By using Test Classes, we can maintain the Code Quality (Code Coverage), so
that it should not impact on the Cloud.
Note:
Upon moving the code from SandBox to SandBox, code coverage is not
required. But while moving the code from SandBox to Production, we have to maintain
min. 75% of the Code Coverage.
Note:
Each Trigger should have min. 1% of Code Coverage. Else we can't deploy
to production.
Note: Test Classes should be prepared for th below Business Logic Components.
Apex Classes
Triggers
Batch Classes
Schedule Classes
VF Controller Classes
WebServices / API's.
Note: For the Configuration features, we no need to prepare the Test Classes.
Before moving the code, we have to estimate the Organization's Code Code as
below.
We can verify each Business Logic Class / Trigger Code Coverage by using the
below navigation.
We can see all the Code Components Code coverage at one place by using the
below navigation.
Goto Your Name and expand it (Ex: Training Batch)
1. Click on "Developer Console" link.
2. Goto the Developer Console Editor.
3. Expand the TabBar.
4. Click on the "Tests" Tab.
5. View the Code Coverage of all the Apex Classes, Triggers at
one place in the form of a Tabular format.
Note:
For each Trigger and Business Logic Class, we have to prepare a
separate Test Class.
Upon preparing the Test Class, we have to follow the below naming
conventions / coding standards.
Ex:
Business Logic Class Name: AccountsHelper
Test Class Name: AccountsHelperTest
Note:
Commented Lines of Code and Test Class Code characters will not be
counting as part of our Organization's Apex Characters Limit.
Note:
Test Class Access specifier should be always either "Private / Public".
Upon preparing the Test Class, we have to follow the below steps.
Step 1: Prepare a Test Class withe the required name and make sure the class
should be pre-fixed with the annotation "@isTest".
Syntax:
@isTest
[Private / Public] Class <TestClassName>
{
// Write the Code to Test the Business Logic..
}
Ex:
@isTest
Private Class AccountsHelperTest
{
// Write the Testing Code..
}
@isTest
Private Class AutoLeadConvertTriggerTest
{
// Write the Testing Code..
}
Step 2: Prepare the Test Method inside the Test Class. Which will invoke
automatically upon testing the business logic.
Rules:
1. Test method should be always a "Static" method.
2. Test Method doesn't return any value to the calling
environment.
Hence the return type should be always "Void".
3. Test Method should be always defined by using the keyword
"testmethod".
4. We can call / invoke the normal / business methods from the
TestMethod.
Syntax:
Static testmethod void <MethodName>()
{
// Write the Testing Code..
}
Ex:
@isTest
Private Class AccountsHelperTest
{
static testmethod void TestAccountsLogic()
{
// Write the Testing Code..
}
}
Standard Navigation:
Setup --> Build --> Develop --> Apex Classes.
Open the Test Class.
1. Click on "Run Test" button.
Standard Navigation:
Setup --> Build --> Develop
1. Click on "Apex Test Execution" link.
2. Select the Test Classes by using the "CheckBoxes".
3. Click on "Run Test" button.
Standard Navigation:
Setup --> Build --> Develop
1. Click on "Apex Classes" link.
2. Click on "Run All Test" button.
Developer Console:
Open the Developer Console.
1. Create the Test Class.
2. Write the Code inside the Test Class.
3. Save the Class Code by using "CTRL+S".
4. Click on "Run Test" button.
UseCase:
========
Create an Apex Class to perform the Mathematical Operations and Prepare the
Test Class to test the Business Logic.
Class Code:
-----------
public class MathOperationsUtility
{
Public static void Addition(integer x, integer y, integer z)
{
system.debug('Addition Result : '+ (x + y + z));
}
MathOperationsUtility.Multiply(20000, 400);
MathOperationsUtility.Division(4500, 20);
MathOperationsUtility.Modulus(400,6);
}
}
UseCase:
========
Write an apex class, to Prepare a collection of Functions to be used to
perform the Mathematical Operations and String Operations. And write the Test Class
for the Business Logic.
Class Code:
-----------
public class CommonUtilityHandler
{
Public static integer Addition(integer x, integer y)
{
return (x + y);
}
system.assertEquals(true, CommonUtilityHandler.CheckEquals('Welcome',
'Welcome'));
system.assertEquals(true, CommonUtilityHandler.CheckEquals('Welcome',
'welcome'));
system.assertEquals(false, CommonUtilityHandler.CheckEquals('Welcome',
'Welcome1')); // Negative Case;
system.assertEquals(true,
CommonUtilityHandler.CheckEqualsWithCase('Welcome','Welcome'));
system.assertEquals(false,
CommonUtilityHandler.CheckEqualsWithCase('Welcome','welcome')); // Negative Case;
system.assertEquals('HelloWelcome',
CommonUtilityHandler.Concatenate('Hello','Welcome'));
}
}
UseCase:
========
Prepare the Test Class for the Trigger, Which Auto Converts the Lead as the
Customer upon updating the Status as "Closed - Converted".
Trigger Code:
-------------
trigger AutoLeadConvertTrigger on Lead (After Update, Before Insert)
{
if(Trigger.isAfter && Trigger.isUpdate)
{
LeadHandlerUtility.AfterUpdate(Trigger.New);
}
Handler Class:
--------------
public class LeadHandlerUtility
{
Public static void AfterUpdate(List<Lead> lstLeads)
{
LeadStatus lStatus = [Select id, MasterLabel, isConverted
from LeadStatus
Where isConverted = true];
lConvert.setLeadId(ldRecord.Id);
lConvert.setDoNotCreateOpportunity(ldRecord.Do_Not_Create_Opportunity__c);
lConvert.setSendNotificationEmail(true);
lConvert.setConvertedStatus(lStatus.MasterLabel);
if(! lstConvert.isEmpty())
{
Database.LeadConvertResult[] result = Database.convertLead(lstConvert,
false);
}
}
insert ldRecord;
update ldRecord;
}
}
UseCase:
========
Prepare the Test Class for the Batch Classes by providing the required Test
Data.
if(hrRecord.Email_ID__c != null)
{
hrRecord.Location__c = 'Hyderabad';
hrRecord.Contact_Number__c = '5555888899';
hrRecordsToUpdate.Add(hrRecord);
}
else
{
hrRecordsToDelete.Add(hrREcord.Id);
}
if(! hrRecordsToUpdate.isEmpty())
{
Update hrRecordsToUpdate;
}
if(! hrRecordsToDelete.isEmpty())
{
Database.delete(hrRecordsToDelete);
}
}
}
MessagingUtilityHelper.SendBatchJobStatusNotifications(jobDetails,'HiringManagerUpd
ateBatch');
}
}
totalAnnualRevenue += acc.AnnualRevenue;
}
}
}
MessagingUtilityHelper.SendTotalRevenueJobStatusNotification(jobDetails,
'CalculateTotalAnnualRevenueBatch', totalAnnualRevenue);
}
}
MessagingUtility Class:
-----------------------
public class MessagingUtilityHelper
{
Public static void SendTotalRevenueJobStatusNotification(AsyncApexJob jobInfo,
string jobName, Decimal revenueAmount)
{
if(jobInfo != null)
{
Messaging.SingleEmailMessage email = new
Messaging.SingleEmailMessage();
email.setReplyTo('customersupport@dell.com');
email.setReplyTo('customersupport@dell.com');
Test Class:
-----------
@isTest
public class HiringManagerUpdateBatchTest
{
static testmethod void TestHiringManagerBatch()
{
CreateHiringManagerRecords();
CreateBulkAccountRecords();
Test.startTest();
Test.stopTest();
}
lstHrRecords.Add(hr);
}
if(! lstHrRecords.isEmpty())
{
insert lstHrRecords;
}
}
lstAccounts.Add(acc);
}
if(! lstAccounts.isEmpty())
{
insert lstAccounts;
}
}
}
UseCase:
========
Create a Test Class for the "Future Method", which will create a Hiring
Manager Record inside the object.
if(userToDeActivate.id != null)
{
userToDeActivate.IsActive = false;
update userToDeActivate;
@future()
Public static void CreateHRRecord()
{
// Create a Hiring Manager Record.. (Non-Setup Object)
Hiring_Manager__C hrRecord = new Hiring_Manager__C();
insert hrRecord;
}
}
Test Class:
-----------
@isTest
public class TestCommonHelper
{
static testmethod void TestFutureMethod()
{
CommonHelper.DoDMLOperations();
}
}
UseCase:
========
Prepare the Test Class for the Queueable Classes.
insert hrRecord;
if(hrRecord.Id != null)
{
system.debug('Hiring Manager Record ID is...: '+ hrRecord.id);
}
}
}
PositionQueueable Class:
------------------------
Global class PositionsQueueable implements System.Queueable
{
/*
* 1. Constructor Name should be always same as the Class Name.
* 2. Constructors are used to assign the default values for the class
members.
* 3. Constructor should be always defined with "Public" access specifier.
* 4. Constructor doesn't have any return type even void.
* 5. Constructor can have one or more parameters.
*/
Hiring_Manager__C hrRecord;
insert pos;
if(pos.Id != null)
{
system.debug('Position Record Inserted with id...: '+ pos.Id);
}
}
}
Test Class:
-----------
@isTest
public class HiringManagerQueueableTest
{
static testmethod void TestQueueableClasses()
{
HiringManagerQueueable hrQueueable = new HiringManagerQueueable();
hrQueueable.Execute(null);
}
}
UseCase:
========
Prepare the Test Class to Test the Apex Sharing Process by using Invocable
Methods.
accShare.AccountId = acc.Id;
accShare.UserOrGroupId = acc.Share_Record_To_User__c;
accShare.RowCause = 'Manual';
accShare.OpportunityAccessLevel = 'READ';
accShare.CaseAccessLevel = 'READ';
if(! shareAccountRecords.isEmpty())
{
Insert shareAccountRecords;
}
}
}
}
if(counter >= 3)
acc.AnnualRevenue = 5700000;
else
acc.AnnualRevenue = 4400000;
acc.Industry = 'Banking';
acc.Phone = '9900998877';
acc.Fax = '9988776655';
acc.Website = 'www.gmail.com';
acc.Type = 'Prospect';
acc.Active__c = 'Yes';
acc.CustomerPriority__c = 'High';
acc.Ownership = 'Public';
acc.Share_Record_To_User__c = CreateUserRecord();
lstAccounts.Add(acc);
}
if(! lstAccounts.isEmpty())
{
Insert lstAccounts;
insert testUSer;
return testUSer.Id;
}
}
UseCase:
========
Prepare a Test Class for the below Visualforce Controller.
VF Page Code:
-------------
<apex:page controller="ShowAccountRecordsController" setup="false" sidebar="false"
showheader="true" tabStyle="Position__c" >
<apex:sectionHeader title="Accounts" subtitle="All Accounts"/>
<apex:form >
<apex:pageblock title="Account Records : ( {!lstAccounts.size} )">
</apex:pageblock>
</apex:form>
</apex:page>
Controller Class:
-----------------
public class ShowAccountRecordsController
{
Public List<Account> lstAccounts{get;set;}
Test Class:
-----------
@isTest
private class ShowAccountRecordsControllerTest
{
static testmethod void TestAccountsController()
{
// Create the Account Records..
CreateAccounts();
if(counter >= 3)
acc.AnnualRevenue = 5700000;
else
acc.AnnualRevenue = 4400000;
acc.Industry = 'Banking';
acc.Phone = '9900998877';
acc.Fax = '9988776655';
acc.Website = 'www.gmail.com';
acc.Type = 'Prospect';
acc.Active__c = 'Yes';
acc.CustomerPriority__c = 'High';
acc.Ownership = 'Public';
lstAccounts.Add(acc);
}
if(! lstAccounts.isEmpty())
{
Insert lstAccounts;
}
}
}
UseCase:
========
Prepare the Test Class for the Visualforce Controller Class, which is used to
Search for the Accounts based on the Search Text.
VF Page Code:
-------------
<apex:page controller="SearchRecordsController" setup="false" sidebar="false"
showHeader="true" tabStyle="Customer__c" >
<apex:sectionHeader title="Accounts" subtitle="Search Accounts"/>
<apex:form >
<apex:Pageblock title="Search Accounts Block">
<apex:pageblocksection title="Search Acounts Section" columns="2"
collapsible="false">
<apex:inputtext label="Enter Search Text : " html-placeholder="Enter
Search Text" value="{!searchText}"/>
<apex:commandButton value="Search Accounts" action="{!
SearchAccountRecords}" rerender="pgBlock" />
</apex:pageblocksection>
</apex:Pageblock>
</apex:pageblock>
</apex:form>
</apex:page>
Controller Class:
-----------------
public class SearchRecordsController
{
Public string searchText{get;set;}
Public List<Account> lstAccounts{get;set;}
Test Class:
-----------
@isTest
Private class SearchRecordsControllerTest
{
static testmethod void TestSearchController()
{
// Insert the Account Records (Prepare Test Data)
CreateAccounts();
if(counter >= 3)
acc.AnnualRevenue = 5700000;
else
acc.AnnualRevenue = 4400000;
acc.Industry = 'Banking';
acc.Phone = '9900998877';
acc.Fax = '9988776655';
acc.Website = 'www.gmail.com';
acc.Type = 'Prospect';
acc.Active__c = 'Yes';
acc.CustomerPriority__c = 'High';
acc.Ownership = 'Public';
lstAccounts.Add(acc);
}
if(! lstAccounts.isEmpty())
{
Insert lstAccounts;
}
}
}