Menu Bar

Wednesday 22 August 2012

TESTING BEST PRACTICES

SALESFORCE: TESTING BEST PRACTICES


Who is this post for?

  • All amateur or proficient salesforce administrators, developers and project managers who want to make their lives easier throughout their salesforce.com journey.
  • Finally, our “Reviewer” who may want to note down our practices for our next “skills review meeting” ;)

What will you learn?

  • The role of administrators (point and click) and process managers in this unit testing and to be aware of how test classes work.
  • Writing “Test Classes” in the best way to ensure code reliability and scalability.
  • Points to remember about unit testing in Salesforce.
Lets start!
Before we begin, let us ask this question first;
who loves writing test classes and doing code review?
we know, nobody is going to raise his hand…..okay, lets frame this way:
who doesn’t want to be blamed when your code fails due to governor limits, unexpected errors and exceptions or for any other reason?
Great!….then you are at the right page!

What is testing?

Testing is a formal process, to facilitate the development of robust, error-free code and
verify whether a particular piece of code is working properly or not. It should be a planned activity (NOT AN AFTER THOUGHT), test methods helps us deploy our Apex code to a production environment.  At least 75% code coverage is needed.
Writing test methods should be a critical part of Force.com development and they
are required to ensure your success. They also provides an automated regression testing framework to validate bug fixes or future development enhancements!

Executing Test Methods

How can Salesforce administrators and managers help us (the developers)?

Lets go wild and talk about technical implementations now!

Unit tests are written in Apex code and annotated with the testMethod keyword.

Defining TestMethod

  • Define any method as static and add the keyword testMethod
  • A test method can be defined in any Apex class.
  • A test method can not be defined in an Apex trigger.
  • Test methods cannot be called outside of a test context.
  • Use the @isTest class annotation to define classes that only contain code used for testing your application.
  • Classes defined with the @isTest annotation do not count against your organisation limit of 2 MB for all Apex code.

Testing trigger

A trigger is an Apex code that executes before or after the following types of operations:
  • insert
  • update
  • delete
  • merge
  • upsert
  • undelete
For example, you can have a trigger run before an object’s records are inserted into the database, after records have been deleted, or even after a record is restored from the recycle bin.
Considering a code sample such as this:

To write a testing code for the above code you first need to setup your data, just like a tester does it when he enters manually but here you need to write a code to do that!

  • Use Test.startTest and Test.stopTest to test governor limits.
  • Each test method is allowed to call these methods only once.
  • Use the System.assert methods to verify your data.

Testing visualforce controller

Developers can use visualforce to create a visualforce page definition. A page definition consists of two primary elements:
  • visualforce markup
  • A visualforce controller

Visualforce markup

Visualforce markup consists of visualforce tags, html, JavaScript, or any other web-enabled code embedded within a singletag. The markup defines the user interface components that should be included on the page, and the way they should appear.

Visualforce controllers

A visualforce controller is a set of instructions that specify what happens when a user interacts with the components specified in associated visualforce markup, such as when a user clicks a button or link. Controllers also provide access to the data that should be displayed in a page, and can modify component behavior.
Considering you have created a testPage which accepts “name” as a parameter, the following should be the way to write a test code for this;

Testing Apex webservice and callouts

Apex supports the ability to write Apex logic and expose the logic as a web service. Therefore an external application can invoke this Apex web service to perform custom logic.
If in the following way you build request, invoke webservice and handle response:



then your testing code should look like this:

Testing SOSL

SOSL statements evaluate to a list of lists of sObjects, where each list contains the search results for a particular sObject type.
SOSL allows you to specify the following for source objects:
  • text expression
  • scope of fields to search
  • list of objects and fields to retrieve
  • conditions for selecting rows in the source objects
Pass the entire SOSL expression in the search parameter of the search() call.
  • Any Salesforce Object Search Language (SOSL) query that is added to an Apex test method returns an empty set of search results when the test method executes.
  • Use the Test.setFixedSearchResults system method to define a list of record IDs that are returned by the search.

Testing Batch Apex

In Salesforce, we employ batch Apex to build complex, long-running processes on the Force.com platform. To use batch Apex, you must write an Apex class that implements the Salesforce-provided interface Database.Batchable, and then invoke the class programmatically.
  • You can test only one execution of the execute method.
  • Use the test methods startTest and stopTest around the executeBatch method to ensure it finishes before continuing your test.
  • Starting from API version 22.0, exceptions that occur during the execution of a batch Apex job that is invoked by a test method causes a failure.
  • If you want to handle exceptions in the test method, enclose the code in try-catch statements.

Bird’s-eye view

There are some points which should be always kept in mind in writing test classes.

Conclusion

Do not underestimate test methods development and put in it as much effort as you can!

“The more you sweat in peacetime, the less you bleed in war!”

No comments: