How to work on Apex Tests efficiently and effectively?

You are enforced to write Apex test code if you need to deploy your code into production. You may notice that more and more time is spent on Apex test code, while the code also becomes harder and harder to maintain. You start wondering if there’s an easier way of writing Apex test code while keeping it easy to maintain.

Since it’s test code, you don’t want to invest much time on it. Most of your test code is flat and unstructured. This is the reason why your Apex test code takes more time to implement and becomes harder to maintain when your code base grows.

You should treat the test code the same as your production code and design some sort of structure for it. The purpose of the design is to increase the code reusability and make it easy to maintain. This article tries to solve the problem with the “Template method” design pattern. You put the common or shared logic and process into the base class and use sub-classes for the variant part of the test cases.

Normally a standard Apex test method comprises the following parts:

  1. Initialize – such as creating test users and assigning profiles or permission sets
  2. Prepare – such as loading initial data
  3. Setup test data – set the key or critical part of the test data
  4. Kick-off test process – launch the business process of the test scenario
  5. Read result data – read the test result
  6. Validate result – validate (assert) the result

For a given test scenario, most of the time the differences between every test cases are in the “Setup test data” (#3) and “Validate result” (#6) steps. We can create a base class to implement the overall test flow and shared test code. The unique(variant) features are implemented in the subclass of the test cases.

Capture

Here are the general ideas to develop an Apex test class for a given test scenario:

  • Create an Apex Test class for the given test scenario
  • Create test methods (@isTest) for each of the test cases
  • Create a virtual BaseTester inner class within the Apex test class
  • Create six virtual methods in the BaseTester class
  • Implement common or shared virtual methods of the BaseTester class
  • Create a public runTest() method and implement the test flow
  • Create sub-classes for each of the test cases and implement the setupTestData() and validate() methods for its unique test requests.
  • Implement each of the test methods by instantiating the correspondent child tester class and executing “runTest” method.

* ctx member object (type of Map) is used to pass data between different methods.

Let’s deep dive into it with a sample scenario.

  • Scenario

The business requests the previously used last name of a Contact needs to be saved for future reference when it’s changed by the user or process. The previous used last name is stored in the Prev_Lastnames__c custom field of Contact object. If there is more than one previously used last name, the multiple previously used last names are stored in a comma separated string. No duplicate previously used last name is allowed.

  • Test Cases
    1. validate if the Prev_Lastnames__c is not changed when the last name is NOT changed on updating.
    2. validate if previous used last name is set to the Prev_Lastnames__c when Prev_Lastnames__c is empty.
    3. validate if previous used last name is added to the beginning of the Prev_Lastnames__c when Prev_Lastnames__c contains value other than the new added last name.
    4. validate if previous used last name is NOT added to the beginning of the Prev_Lastnames__c when Prev_Lastnames__c already contains the last name to add.
    5. validate if previous used last name is added and the earliest added last name is removed when the Prev_Lastnames__c field exceeds the field length.

The business logic is implemented in the update trigger of Contact object. We need to write Apex test code for the given test cases.

First, we will create an Apex test class called PrevUsedLastNamesTests for the scenario and implement each test case as a test method. Here is the skeleton of the test class named PrevUsedLastNamesTests with five test methods.

@isTest
private class PrevUsedLastNamesTests {
    @isTest
    static void testLastNameNotChange() {
    }

    @isTest
    static void testNewLastNameForEmptyPrevNames() {
    }

    @isTest
    static void testNewLastNameForNotEmptyPrevNames() {
    }

    @isTest
    static void testExistingLastName() {
    }

    @isTest
    static void testExceedingFieldLenOfPrevNames() {
    }
}

Second, we must implement the BaseTester class as the template for the sub-classes.

    virtual class BaseTester {
        Map ctx;

        BaseTester() {
            ctx = new Map();
        }
        /*
         * @description Entry point to execute the individual test case
         */
        public void runTest() {
            // System.runAs(user) {
            initialize(ctx);
            prepare(ctx);
            setupTestData(ctx);
            executeProcess(ctx);
            readResultData(ctx);
            validate(ctx);
            // }
        } 

        protected virtual void initialize(Map ctx) {}
        protected virtual void prepare(Map ctx) {
            Contact c = new Contact(
                FirstName = 'John',
                LastName = 'Smith'
            );
            insert c;

            ctx.put('contact', c);
        }

        protected virtual void setupTestData(Map ctx) {}
        protected virtual void executeProcess(Map ctx) {
            Contact c = (Contact)ctx.get('Contact');
            update c;
        }

        protected virtual void readResultData(Map ctx) {
            Contact c = (Contact)ctx.get('contact');
            Contact updatedContact = [SELECT FirstName, LastName, Prev_Lastnames__c FROM Contact WHERE Id=:c.Id];
            ctx.put('updatedContact', updatedContact);
        }
        protected virtual void validate(Map ctx) {}
    }

Here are the highlights of the BaseTester class:

  • runTest(ctx) method executes the test flow by calling each of the virtual methods.
  • prepare(ctx) method creates a new Contact object for later usage. Notice how we use the ctx object to store and pass the newly created contact to other methods.
  • executeProcess(ctx) method triggers the actual business flow by updating the given contact.
  • readResultData(ctx) method reads the updated Contact record out and stores it into ctx for the validate(ctx) method.

Since we implemented the skeleton for the given test scenario, we can work on the individual sub-class for each of the test cases. Let’s still use #2 test case as an example and you can see how simple and easy it is.

    class NewLastNameForEmptyPrevNamesTester extends BaseTester {
        override void setupTestData(Map ctx) {
            String newLastName = 'Rees';
            ctx.put('newLastName', newLastName);
        }

        override void validate(Map ctx) {
            Contact updatedContact = (Contact)ctx.get('updatedContact');
            System.assertEquals('Smith', updatedContact.Prev_Lastnames__c);
        }
}

    @isTest
    static void testNewLastNameForEmptyPrevNames() {
        (new NewLastNameForEmptyPrevNamesTester()).runTest();
    }

In the sub-class for the specific test case, you only need to pay attention to the key test data (new value for LastName field) and the validation (assertion) rule for the updated value in the Prev_Lastnames__c field.

The same pattern can be applied to the rest of test cases. You can download the full set of code from GitHub.

References:

Template method pattern

GitHub Repo for the sample scenario

 

Advertisements
Posted in Apex Test, Force.com, Salesforce, Software Development, Uncategorized | Leave a comment

Agile: Make meetings more productive

There’re many meetings in Agile, such as daily stand-up, release planning, sprint planning, backlog grooming, sprint retrospective, release retrospective and sprint review meetings. Those meetings require all the team members and usually take about 10 hours in total per sprint.That’s about 12.5% of all the total available time for every scrum member and a big overhead for development process. Working on making it more efficient will help the productivity of your scrum team.

Do we need all the meetings for every sprint?

All meetings are valuable, but do you really need all of them in every sprint? Do you consider drop some sprint retrospective meetings if your sprint goes well? Keep in mind that the purpose of meeting is achieve some targets instead of gathering people together. Think about this, do I really need a meeting to achieve the target(s)?

Do we need all scrum members for all the meetings?

The involvement of whole team is great but it costs time. The backlog grooming (refinement) meeting is an example of it.The purpose of the meeting is to get the backlog items estimated and prioritized correctly for the sprint planning meeting. You could possibly only involve the product manager/owner, lead BA, QA and developer in the meeting.

Can we cut some meetings short?

I always consider how the sprint planning meeting can be more productive, especially for the part of breaking up the user story into tasks. It is very inefficient to have everyone sitting together to break up all the tasks for all user stories. One suggestion is to split the meetings into two. The first meeting is to pre-assign the user stories to scrum members to create tasks according to their specialties. The second part is to review the tasks and adjust assignments of user stories and tasks if needed.

Helpful links

Backlog Grooming: Who Should Attend and How to Maximize Value

7 Mistakes During the Daily Stand-up Meeting

Posted in Agile, Backlog Refinement, Software Development, Sprint Planning, Sprint Review, Uncategorized | Tagged , , | Leave a comment

Migrating <apex:InputField/> Visualforce Component into Lightning Experience World

Code on GitHub

Salesforce is quickly moving into the new Lightning Experience world. As a traditional Visualforce developer, how can you catch up to this fast moving Lightning Experience train?

Salesforce will eventually upgrade all the Visualforce components to support Lightning Experience. It won’t be ready until 2017. Since Lightning Design System is an open standard, you can use it to develop the Visualforce app with the look and feel of Lightning Experience.

The trailhead project “Build a Visualforce App with the Lightning Design System” is a good start, but it does not tell you how to upgrade the <apex:InputField/> component. The data binding and dynamic rendering (via SobjectField type) features make it a big challenge to be upgraded into Lightning Experience style.

The <c:LexInputField/> custom Visualforce component is designed to solve this challenge. It uses the similar syntax as <apex:InputField/> component, supports data binding and can be rendered promptly according to the SobjectField type. All the native features of <apex:InputField/> are supported by the new custom component.

Syntax:

<c:LexInputField SObject=”[sObject]” Field=”[fieldName]“></c:LexInputField>

Attributes:

Name Type Description Required
SObject SObject A merge field represents SObject which the component is associated with. Yes
Field String Name of the field on the SObjecd which the component is associated with. Yes

Example:

Let’s see how <c:LexInputField/> is rendered with the following example. All the input controls on the Visualforce are created with <c:LexInputField/>. You will see they all get the same look and feel as Lightning Experience.

image

Here is the source code for the Visualforce.

<apex:page standardStylesheets="true" applyBodyTag="false" docType="html-5.0" standardController="LexForce__c" extensions="LexForceController" >
    <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <head>
            <apex:stylesheet value="{!URLFOR($Resource.SLDS, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />
        </head>
        <apex:form >
<div class="slds">
<div class="slds-form--stack">
                    <c:LexInputField SObject="{!LexForce}" Field="Name"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Account__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Checkbox__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Currency__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Date__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Datetime__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Email__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Geolocation__Latitude__s"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Geolocation__Longitude__s"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Number__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Percent__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Phone__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Picklist__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="MultiPicklist__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="Text__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="TextArea__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="TextAreaLong__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="TextAreaRich__c"></c:LexInputField>
                    <c:LexInputField SObject="{!LexForce}" Field="URL__c"></c:LexInputField>
<div class="slds-button-group" role="group">
                        <apex:commandButton action="{!save}" value="Save" id="btnSave" styleClass="slds-button slds-button--neutral"/>
                        <apex:commandButton action="{!cancel}" value="Cancel" id="btnCancel" styleClass="slds-button slds-button--neutral"/></div>
</div>
</div>
</apex:form>
    </html>
</apex:page>

 

Let’s see how Lookup field behaves after migration.

<c:LexInputField SObject=”{!LexForce}” Field=”Account__c”></c:LexInputField>

After you click the “search” button, a standard SFDC Lookup dialog pops up. This dialog is not polished with SLDS but it gives you the full functionalities of the lookup field.

image

If you turn on the auto-complete feature for the Account lookup field, the OOTB type ahead feature also works for you. Amazing!

image

In order to use the <c:LexInputField/> component, you need add Lightning Design System to your org.

<apex:stylesheet value=”{!URLFOR($Resource.SLDS, ‘assets/styles/salesforce-lightning-design-system-vf.css’)}” />

The sample project uses release version 0.12.1. Please also pay attention to how Visualforce is constructed. There’re some basic requirements to develop a Visualforce page with Lightning Design System. Please check the Trailhead Visualforce & Lightning Experience  for details.

The source code for <c:LexInputField/> and demo page can be found on Git Sfdc-Lexforce repository. This custom component is just a start, you can customize it for your Visualforce application.

Caveat:

Since the SLDS for MultiPicklist is still in development stage, there’re issues when the <c:LexInputField/> is used for MultiPicklist field.

Code on GitHub

Posted in Computers and Internet, Force.com, Lex, Lightning Design System, Lightning Experience, Salesforce, SLDS, Software Development, Visualforce | 30 Comments

Options To Develop Lightning Experience App for Salesforce Winter 16 Release

Salesforce announced the new Lightning Experience for its Winter 16 Release. Compared with the classic UX, the Lightning Experience UX is so stunning that everyone wants it after trying it. As a developer, you also want to develop your new SF app with such amazing technology. Since Lightning Experience is pretty new, what’s the best practice for you to work with it?

The cornerstone of the Lightning Experience is the Salesforce Lightning Design System (SLDS for short reference). SLDS is very similar to other CSS frameworks, such as BootStrap, but it’s Salesforce proprietary technology that is used to develop the new Lightning Experience.

Lightning Component Framework is different from Lightning Experience. It’s a Javascript framework SFDC designed to build responsive applications. It definitely will have better integration with Lightning Experience in the future; but you still need copy and paste markups from SLDS for now.

There are several approaches to develop a Lightning Experience application.

image

Approach 1: Lightning Component Framework + SLDS

This might be the internal technology stack used by Salesforce to develop Lightning Experience. Lightning Component framework itself is just a Javascript framework and has nothing to do with the Lightning Experience. You still need to incorporate SLDS to develop Lightning Experience application.

Please read Build a Lightning App with the Lightning Design System for more information.

With this approach, the new page is not available in the Classic Experience unless you create a standalone app for it.

Approach 2: Visualforce Container + 3rd JS Framework + SLDS

You will use Visualforce as a page container and put the SLDS CSS and markup into your page. You can use 3rd JS framework (such as Angular JS) to develop client-side page behavior and Javascript Remoting or Visualforce Remote objects to access data on the server.

Please read Understanding Important Visual Design Considerations for more information.

Approach 3: Visualforce Container + Lightning Out + SLDS

This is a hybrid approach. You use Lightning Component framework and SLDS to develop reusable Lightning Experience components. You can seamlessly embed those components into your VF page with Lightning Out technology.

You cannot use Lightning App/Component directly in the classic UI with the new Lightning Experience. With this approach, your Lightning components can be displayed in the Classic UI within a Visualforce page.

Lightning Out is GA for Winter 16 release. Please read Add Lightning Components to Visualforce Pages for more information.

Lightning Component Framework plus SLDS might be your the preferred approach, but please think about the following constraints before you choose it.

  • Pure Lightning Component/App cannot be used in the classic UI. You have to use Lightning Out technology to expose it in classic UI.
  • Force.COM IDE does not support the development of Lightning component/app. It might be an issue for you if you use a version control system.
  • Lightning Component Framework is pretty new. You might encounter unexpected issues.

Caveat for SLDS:

Currently only IE11 is officially supported by SLDS. If you have a lot of customers still using IE 10 or 9, you need to consider if it’s the right time to adopt SLDS.

Posted in Javascript, Lightning Experience, Salesforce, Software Development | Tagged , , , | Leave a comment

Implement Polymorphism for Custom Objects and Fields in Salesforce

Polymorphic Id field is a lookup field which can reference several different type of SObjects, such as the Whoid and Whatid field on the Event object. As of now, the Polymorphic Id field is only available in standard fields. Please vote for the idea Custom Polymorphic Id field (WhoId/WhatId) if you think that it’s an important feature for you.

This article will discuss how to implement the polymorphic behavior for your custom fields. Let’s assume you have the following business requests:

  1. Three custom media objects need to be created, Image__c, Audio__c and Video__c.
  2. A lookup field (Account__c) to Account on each media object needs to be created.
  3. A media request object (MediaRequest__c) needs to be created to represent to request to media object.
  4. A lookup field (Media__c) on MediaRequest__c object needs to be created. The target the lookup field can be either Image__c, Audio__c or Video__c object.
  5. ONE related list for all associated related media objects needs to be created on Account object.

#4 and #5 are typical polymorphic behavior requests.

image
ER Diagram

The application will typically be modeled as the diagram shown above. There is no polymorphic behavior support and requests #4 and #5 are not fulfilled.

In order to support the polymorphic behavior, we need to be creative with the data model. Let us check the diagram below.

image
ER Diagram

The major difference from the previous data model is that a Media__c parent (Master-Detail) object is introduced and acts as a bridge for the child media objects to  others (Account and Media_Request__c). The idea is to use Media__c as a proxy. It hides the difference for its child objects and routes all the requests to its child objects.

image

Here are the highlights of the new data model.

  • Media__c object is created as the parent (Master-Detail) to Image__c, Audio__c and Video__c objects.
  • Media_Type__c is a Picklist field on Media__c object which has three values: Image, Audio and Video.
  • Child_Id__c is a TEXT(18) field on Media__c object which is used to store the ID value of the associated child media object. Checking “Unique” checkbox to help to enforce the 1:1 relationship from Media__c to its child objects.
  • Account__c is a Lookup field to Account on Media__c object which is used to eliminate the individual Lookup field on each Image__c, Audio__c and Video__c objects. The benefit is that only one related list is needed on Account page layout instead of three which fulfill the business request #5.
  • ONLY one Media__c Lookup field is created on MediaRequest__c instead of three which fulfill the business request #4.

Here are the reasons why we use “Master-Detail” instead of Lookup to model the relationship from Media__c to its child objects.

  • The same security access is enforced for both Media__c and its child objects. This is important when you need control the sharing for the media objects.
  • The child object will be deleted automatically when parent Media__c object is deleted.

We are done with the declarative development tasks. We now need to dive into the code to play some tricks to fully implement polymorphic behavior requests.

Enforce 1:1 relationships between Media__c and its child object

Similar to the Account and Contact objects in PersonAccount, Media__c and its child object should exist always in-pair. As mentioned before, the Child_Id__c field on Media__c is used to store the Id of the child object. We use trigger to populate the field to establish the 1:1 relationship. The trigger is created on the child objects and populates the Id value to its parent Media__c object.

Code snippet for Audio__c trigger.

image

Since Image__c and Vidoe__c have the same logic, we create the MediaTriggerHandler class to wrap up the logic. You can check the zipped source code at the bottom of this blog.

Redirect Edit/View requests from Media__c to its correspondent child object

Since Media__c is the proxy object, we need to redirect the requests for Media__c object to its child objects. The Edit/View requests can be done with a dispatcher Visualforce page. The dispatcher Visualforce page is used to override the default Edit and View actions of Media__c object.

image

See the code snippet the dispatcher page. The dispatchView() and dispatchEdit() methods will be invoked as the page action which routes the request to its child object.

image

Overide New button requests for Media__c

New request is different from View and Edit requests. We cannot redirect the New request because the the child object is not created yet. We need to create Media__c and its child object in-pair according to the media type selected. We still use Visualforce page (MediaNew) to implement it. The MediaNew Visualforce page is used to override the New action of the Media__c object.

image

Three different Visualforce components are created for each type of media object. Different page logic can be isolated and encapsulated into different Visualforce component.

image

We only add the Name field in each Visualforce component for simplification. Pay attention to see how the child object is passed into Visualforce component.image

In MediaNew Visualforce page, we use <apex:actionFunction/> to control which of the Visualforce component is rendered according to the media type selected.

image

See the finalized MediaNew Visualforce page. Different Visualforce component is displayed for different Media type selected.

image

Now we have done the coding for the polymorphic requests. Let us check how it works.

For the #4 request, only one Lookup field is created and different type of media objects can be selected for the Media Lookup field.

image

For the #5 request, the related list on Account page layout contains mixed type of media objects. The link on the related list will bring you directly to the Edit or View page of the child media object.

image

 

You can download the sample project source files from GitHub.

Posted in Architect, Data Model, Force.com, Polymorphism, Salesforce, Software Development, Visualforce | Tagged , , , | Leave a comment

Salesforce Data Modelling Tip (1) – Create Composite Key for Your Custom Object

In Salesforce, the Id field is the primary key for any SObject. Users can also create a custom text field and make it unique, but users cannot create a composite key for a SObject.

A Composite key is very important in certain scenarios. It will help you maintain the data integrity and is a basic feature in any relational databases. Even though Salesforce uses Oracle, it hides this feature in its Force.com development platform.

Let us assume that you need to develop a Course Registration application. You created two custom Objects, Student__c and Course__c. You want to create a 3rd custom Object called Registration__c to record if a student registers a course or not.

You create two Lookup fields on the Registration__c object, one for Student__c and one for Course__c. You also need to enforce a business rule of which one student can only register for one course.

If you can make the composite key on Registration__c object which includes the Id for Student__c and Course__c, your goal is achieved. Since there’s no OOTB composite key feature for you, you need be creative to figure out an alternative way. Here is the solution for you:

  1. Create a Text field called “Key__c” on Registration__c and make it Unique.
  2. Create a trigger on Registration__c SObject and listen on Before Insert and Before Update events.
  3. In the trigger, assign “Key__c” field with the concatenated value from Student__c and Course__c Id fields.

Bingo, you have done your job. Since this is enforced on the database level, you will never have the same student to register a course twice. Other solutions may still generate a duplicate record if two users submit the request at the same time.

The proposed solution does not create a real composite key but it generates the same result of the composite key.

Posted in Architect, Salesforce, Software Development | Tagged , , , | Leave a comment

Agile vs. Waterfall (1)

Agile has not come from nothing. It evolves from Waterfall. Within Waterfall,  the development process is divided into different milestones (usually 1 month). It also delivers prototype system to clients following each milestone to verify the requirements and receive feedback. It’s already very similar to the Agile process. In essence, it is the predecessor of Agile.

Agile practice should inherit the merits from Waterfall instead of throwing them into the garbage. Practicing Agile is a trend now, but please consider the following questions before you proudly announce yourself as an Agile practitioner.

  • Does your Agile process really help you successfully deliver the product?
  • Does your Agile process really help you reduce the development cost?
  • Does your Agile process really help you speed up your development process?
  • Does your Agile process really help you to promote the quality of your product?
Posted in Software Development | Tagged , , | 2 Comments