BEST PRACTICES FOR WRITING APEX TEST CLASSES IN SALESFORCE



Here are some best practices that we need to be followed while writing test classes in Salesforce:

  1. All test methods should reside in a separate class from the class in which the method being tested resides.
  2. These classes should be perfixed with the word Test the name of the class being tested, e.g. TestReferenceUseRequest.
  3. These classes should all use the @isTest annotation.
  4. There should be a minimum of “Null Pointer Exception test” as part of negative testing for each method, specially the methods that accept parameters.
  5. A method without an assert statement is not considered a test method. Large number of relevant assert statements increases confidence in the correct behaviour of business logic.
  6. There should be a comment with each assert statement explaining what is being tested and what the expected output is.
  7. Only use isTest(SeeAllData = true) on class methods in exceptional cases where there are sObjects that doesn't allow DML operation e.g. PriceBook creation.
  8. No hard coded ids of any sObject in any test method.
  9. If a Constant needs to be asserted ,its a best practice to reference that from the Constant class or from Custom Labels or Custom Settings. Using hard coded string in unit tests( or any class for that matter) will trigger failures when things like Picklist values change.
  10. All test data creation should be done from a Utility class. This allows for a streamlined creation of test objects that adhere to all the validation rules.
  11. Creating multiple test method for testing that same production code method should be avoided. We want to ensure that our unit test methods are properly testing the logic but the same time the efficiency of the unit test method should not be ignored. All the unit test methods run with every deployment so the cumulative run time should be as small as possible.
  12. All private methods should also have its corresponding unit test method. In the production code, add a public method for each private method.
  13. Any asynchronous method testing should include Test.startTest and Test.stopTest. Test.stopTest forces the asynchronous methods to run so the results could be asserted.
  14. Any exceptions that are caught in the production methods should be tested by feeding the test data that throws exception. Exception Type and error message should be asserted.
  15. Every class should have test coverage close to 95% as possible. The focus should be on asserting method behaviour rather than increasing coverage. There are very few instances where a method behaviour is not straightforward to reproduce and hence test. These should be properly commented.
  16. Avoid Try/Catch blocks in test methods.
  17. Any business logic that needs to be tested should be enveloped within a Test.runAs(user) statement so profile restrictions can be tested. . Using any admin profiles should be avoided.
    For Example:A new test user is created, then code is run as that user, with that user's record sharing access:
    @isTest
    private class TestRunAs {
      public static testMethod void testRunAs() {
         // Setup test data
        // This code runs as the system user
         Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
         User u = new User(Alias = 'standt', Email='standarduser@testorg.com',
         EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
         LocaleSidKey='en_US', ProfileId = p.Id,
         TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');

         System.runAs(u) {
            // The following code runs as user 'u'
            System.debug('Current User: ' + UserInfo.getUserName());
            System.debug('Current Profile: ' + UserInfo.getProfileId());
         }
      }
    }

 

0 comments: