Testing is the major thing of the development. In salesforce, Apex Code requires the creation and execution of unit tests. Unit tests are class methods that verify whether a particular piece of code is working properly or not. Unit tests are written in Apex Code and annotated with the “testMethod” keyword.
Important things to note down before to write TestClass:
– At least 75% of code coverage is required to move the apex code to production from sandboxes.
– Whatever we created the data in test class that won’t save in database. (delete all the data once transaction is done)
– Do not write any SOQLs in test class.
– Do not use “seeAllData=true”, Create own data in test class.
– Use As much as Assertions like “System.AssertEquals” or “System.AssertNotEquals”
– To reset the Governor limits for the particular transcation use system.startTest()
and system.stopTest()
Writing a simple Unit Test Class:
Apex Class:
public class NewAccountCreation {
public Account account{get;set;}
public void save(){
Account acc = new Account();
// User enter values in vf page and we are capturing and creating account
acc.name = account.Name;
acc.adress = account.adress;
Insert acc;
}
}
Unit Test class for above apex Class:
@isTest
private class NewAccountCreationTest{
public static testMethod void NewAccountCreationTestMethod(){
NewAccountCreation accountCreation = new NewAccountCreation ();
Account acc = new Account();
acc.name = ‘NewAccount’;
acc.address = ‘bangalore’;
insert acc;
accountCreation.save();
}
}
Important things to note down before to write TestClass:
– At least 75% of code coverage is required to move the apex code to production from sandboxes.
– Whatever we created the data in test class that won’t save in database. (delete all the data once transaction is done)
– Do not write any SOQLs in test class.
– Do not use “seeAllData=true”, Create own data in test class.
– Use As much as Assertions like “System.AssertEquals” or “System.AssertNotEquals”
– To reset the Governor limits for the particular transcation use system.startTest()
and system.stopTest()
Writing a simple Unit Test Class:
Apex Class:
public class NewAccountCreation {
public Account account{get;set;}
public void save(){
Account acc = new Account();
// User enter values in vf page and we are capturing and creating account
acc.name = account.Name;
acc.adress = account.adress;
Insert acc;
}
}
Unit Test class for above apex Class:
@isTest
private class NewAccountCreationTest{
public static testMethod void NewAccountCreationTestMethod(){
NewAccountCreation accountCreation = new NewAccountCreation ();
Account acc = new Account();
acc.name = ‘NewAccount’;
acc.address = ‘bangalore’;
insert acc;
accountCreation.save();
}
}
Keywords or functions in Test classes:
@isTest Annotation:
This annotation is used to define the test class. If we use this annotation then data which we created inside the method doesn’t count against your organization limit. Can be created the method declared as “private” or “public”.
seeAllData:
If we use this keyword seeAllData=true , then we get all the data from database. This will be a problem because the data is vary from instance to instance. seeAllData=false, is not access to the data in the system ,whatever the data need in the test class we have to create in class it self.
System.runAs():
This keyword/function is used only in test method, generally Apex code is running in system mode not in user mode and permission and record sharing of the current user are not taken as count.
If we have to call the piece of code which will be execute with specific user then we can use this function.
Test.isRunningTest():
This keyword/function we can use only in classes not in test classes. When we have to call the piece of code only from test class then we can use this. This is Boolean variable return true when calling from test class otherwise false.
How to Write test class for trigger:
Here is the example to write a test class for a simple Apex Trigger.
Following trigger is executed whenever account is created and creates sharing to the manager to that record.
Apex Trigger Code:
trigger accountAfterInsert on Account (after insert) {
string managerId= [Select Id, ManagerId FROM User WHERE Id =:userInfo.getUserId()].ManagerId;
for(Account acc: trigger.New){
AccountShare accShare = new AccountShare();
accShare .ParentId = acc.Id;
accShare .UserOrGroupId = managerId;
accShare .AccessLevel = ‘EDIT’;
accShare .RowCause = Schema.accountShare.RowCause.Manual;
}
}
Test Class for above Trigger:
@isTest
private class AccountTriggersTest{
private static testmethod void accountTriggersTest(){
Account acc = new Account();
acc.name = ‘NewAccount’;
acc.address = ‘USA’;
insert acc;
}
}
How to use system.runAs()?
Here is the example to use System.runAs() in apex test class: For example we have a class to create the campaign only if logged in user is marketing profile otherwise throwing error.
Apex Trigger:
trigger campaignBeforeInser on Account (before insert) {
for(Campaign campaign: trigger.new){
if(userInfo.getProfileId == ‘marketing profile Id’){
campaign.currency = ‘USD’;
}
else{
campaign.addError(‘you are not authorized to create campaign’);
}
}
}
Here is the Test class for above trigger:
@isTest
private class CampaignTriggersTest{
private static testmethod void campaignTriggersTest(){
Profile prof = [select id from profile where name LIKE ‘%marketing%’];
User user = new User();
user.firstName = ‘test1’;
user.lastName = test2;
user.profileId = prof.id,username = ‘test@test.com’;
user.email = ‘test@test.com’;
insert user;
system.runAs(user){
Campaign camp = new Campaign();
camp.name = ‘laptop’;
insert camp;
}
}
}
How to write a test class for Scheduler and Batches:
Here is the example to Write test method for Scheduler and Batch Apex Classes:
Example: This batch Apex is to Approving the opportunities which are in submitted status.
Batch Class:
global class OpportunityBatch implements database.batchable<sObject>{
global String opptyList;
global Database.QueryLocator start(Database.BatchableContext info){
String status = ‘Submitted’;
opptyList = ‘select name,AccountName__c from Opportunity where status__c =\”+ status +’\” ;
return Database.getQueryLocator(opptyList);
}
global void execute(Database.batchableContext info,List<Opportunity> opptyList){
List<Opportunity> opportunitiesList = new List< Opportunity >();
for(Opportunity oppty: opptyList){
oppty.status__c = ‘Approved’;
opportunitiesList.add(oppty);
}
Insert opportunitiesList;
}
global void finish(Database.batchableContext info){
}
}
Scheduler:
global class OpportunityScheduler implements Schedulable{
global void execute(SchedulableContext sc){
OpportunityBatch batch = new OpportunityBatch();
if(!Test.isRunningTest()){
database.executebatch(batch);
}
}
}
Test Class For Batch Class:
@istest
public class OpportunityBatchtest{
//query the activities to process
static testmethod void OpportunityTestMethod(){
Opporunity oppty = new Opportunity ();
oppty.name = ‘test Oppty’;
oppty.status__c = ‘submitted’;
insert oppty;
OpportunityBatch opptybatch = new OpportunityBatch ();
Status = ‘Submitted’;
opptybatch.opptyList = ‘select name,AccountName__c from Opportunity where status__c =\”+ status +’\’ and id=\’ AND Id=\”+claim.id+’\”;
Database.executebatch(opptybatch);
}
}
Test Class For Scheduler Class :
@istest
class OpportunitySchedulerTest{
public static testMethod void testschedule() {
Test.StartTest();
OpportunityScheduler testsche = new OpportunityScheduler();
String sch = ‘0 0 23 * * ?’;
system.schedule(‘Test status Check’, sch, testsche );
Test.stopTest();
}
}
Test Class for Controller class
Test Class for StandardSetController
Test
Class for Standard Controller
@isTest public class ExtensionTestClass { static testMethod void testMethod1() { Account testAccount = new Account(); testAccount.Name='Test Account' ; insert testAccount; Test.StartTest(); PageReference pageRef = Page.AccountPlan; // Add your VF page Name here Test.setCurrentPage(pageRef);
pageRef.getParameters().put('id', String.valueOf(testAccount.Id));
ApexPages.StandardController sc = new ApexPages.StandardController(testAccount); myControllerExtension testAccPlan = new myControllerExtension(sc);
//testAccPlan.save(); call all your function here
Test.StopTest();
}
}
Test Class for Controller class
@isTest public class ControllerTestClass { static testMethod void testMethod1() { Account testAccount = new Account(); testAccount.Name='Test Account' ; insert testAccount; Test.StartTest(); PageReference pageRef = Page.AccountPlan; // Add your VF page Name here pageRef.getParameters().put('id', String.valueOf(testAccount.Id)); Test.setCurrentPage(pageRef); myController testAccPlan = new myController(); //testAccPlan.save(); call all your function here Test.StopTest(); } }
Test Class for StandardSetController
@isTest public class TestStandardSetController { static testMethod void testMethod1() { List <Account> lstAccount = new List<Account>(); Account testAccount = new Account(); testAccount.Name='Test Account' ; lstAccount.add(testAccount); Account testAccount1 = new Account(); testAccount1.Name='Test Account1' ; lstAccount.add(testAccount1); insert lstAccount; Test.startTest(); Test.setCurrentPage(Page.YOUR_PAGE); ApexPages.StandardSetController stdSetController = new ApexPages.StandardSetController(lstAccount); stdSetController.setSelected(lstAccount); YOUR_Extension ext = new YOUR_Extension(stdSetController); Test.stopTest(); } }
Please
follow below salesforce Best Practice for Test Classes :-
1. Test class must start with @isTest annotation if class class version is more than 25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the percentage of code coverage ,we should make sure that every use case should covered including positive, negative,bulk and single record .
1. Test class must start with @isTest annotation if class class version is more than 25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the percentage of code coverage ,we should make sure that every use case should covered including positive, negative,bulk and single record .
10.
Test class should be annotated with @isTest .
11 . @isTest annotation with test method is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access specifier .
14. classes with @isTest annotation can't be a interface or enum .
15. Test method code can't be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out mock .
19. You can't send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
23. Create TestFactory class with @isTest annotation to exclude from organization code size limit .
24. @testSetup to create test records once in a method and use in every test method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is not grater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the process .
11 . @isTest annotation with test method is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access specifier .
14. classes with @isTest annotation can't be a interface or enum .
15. Test method code can't be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out mock .
19. You can't send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
23. Create TestFactory class with @isTest annotation to exclude from organization code size limit .
24. @testSetup to create test records once in a method and use in every test method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is not grater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the process .
No comments:
Post a Comment