Saturday, March 21, 2015

Testing in Apex

“one unit test is infinitely better than no unit test”

Testing in Apex

Testing is an important part of the development process. Like other programming languages, Apex also provides a testing framework that allows you to write unit tests, run, check and have code coverage of your test results.
In Salesforce before you deploy Apex to your Salesforce.com Production organisation or package it for the Force.com AppExchange, you must have at least 75% of your Apex code covered by unit tests, and all of those tests must complete successfully. 

The most important point and advantage to create a separate class for Apex Test methods is that it does not count against your organisation limit of 3 MB for all Apex code. 

Apex Test Class Syntax:


// This class contains test methods with different data access levels.
@isTest
private class className{
    
    // Method 1
    static testMethod void methodName1(){
              // your logic here
    }
    
    // Method 2
    @isTest static void methodName2(){
              // your logic here
    }
    
    // Method 3
    @isTest (SeeAllData = true)
    static void methodName3(){
              // your logic here
    }
    
    // Method 4
    @isTest
    static void methodName4(){
              // your logic here
    }

}


// All test methods in this class can access all data of Salesforce organisation.
@isTest (SeeAllData = true)
private class className{
    
    // Method 1
    static testMethod void methodName1(){
              // your logic here
    }
    
    // Method 2
    @isTest
    static void methodName2(){
              // your logic here
    }
    Note: You don't need "@isTest (SeeAllData = true)" here because class has already been defined with the @isTest(SeeAllData=true) annotation.

}


First thing to notice is that we use the @isTest annotation. All classes marked with "@isTest" annotation will make classes to run in Testing context only. Also, you see we use "testMethod" keyword and "@isTest" annotation for defining methods within Test classes. Both are interchangeable the only difference is you can access your organisation's data by using "@isTest (SeeAllData = true)" annotation individually with the method.


Winter '12 Features for Apex Testing

With Winter '12 releaseForce.com platform provided you a capability to create Public test classes that expose common methods for test data creation. These public methods can be called by tests outside the test class for setting up data that the tests need to run against.

Methods of a public test class can only be called from a running test, that is, a test method or code invoked by a test method, and can't be called by a non-test request. 

// In this class you can create and expose records to called by other test classes
@isTest
public class TestDataFactory{

    public static Account createTestAccount(){
              // create test Account records
    }
    public static Contact createTestContact(){
              // create test Contact records
    }

}


Spring '12 Features for Apex Testing

Spring '12 release came with a feature "Isolation of Test Data for Unit Test". It means with Spring 12 release you can now explicitly mark your test class "@isTest (SeeAllData = true)" to access your Salesforce organisation data.

As we know all Salesforce metadata components associate to a particular Salesforce API version and every version has dependency based on features.

Spring '12 release came up with Salesforce API version 24.0 and announced that Apex code saved using Salesforce API version 24.0, test classes and methods don't have access by default to pre-existing data in the organisation. So, for Apex code saved using Salesforce API version 24.0 and later, use explicitly the @isTest(SeeAllData=true) annotation to grant test classes and individual test methods access to all data in the organisationBut Test code saved against Salesforce API version 23.0 or earlier continues to have access to all data in the organisation and its data access is unchanged.


Spring '15 Features for Apex Testing

Finally Spring '15 release has came up with a new annotation "@testSetup" which gives you ability to "Setup Test Data for Entire Class".
With Spring '15 release now you create common test records once and access them in every test method in the test class. All methods that are annotated with @testSetup will be called test setup methods.

Syntax for Test Setup Method (@testSetup annotation)

@isTest
private class className{

           @testSetup static void commonmethodName() {
                               // your logic here
           }

           // Method 1
           static testMethod void methodName1(){
                               // your logic here
           }
    
          // Method 2
          @isTest static void methodName2(){
                               // your logic here
          }

}

For further details of @testSetup method see here


Considerations:

  • Use the @isTest annotation to define classes and methods that only contain code used for testing your application. The @isTest annotation on methods is equivalent to the testMethod keyword.
  • Classes and methods defined as @isTest can be either private or public.
  • Classes defined as @isTest must be top-level classes.
  • Classes defined with the @isTest annotation don't count against your organisation limit of 3 MB for all Apex code. 
  • Classes defined as @isTest can't be interfaces or enums.
  • Methods of a public test class can only be called from a running test, that is, a test method or code invoked by a test method, and can't be called by a non-test request.
  • You must have at least 75% of the Apex code coverage in your organisation to be able to deploy the code to your Salesforce production organisation.

Useful Resources: