Some time ago, a request came to the ElmoSoft team to automate testing of a project built on the Salesforce platform. We decided to outline the tasks / ideas and problems that we faced on the project. Since the amount of knowledge and experience gained is quite large, the article will have to be divided into several parts. The first part is rather introductory and gives a general idea of what automation in Salesforce consists of. So, the skepticism in relation to such a task was immediately maximum due to the following stereotypes in my head:
Salesforce is a ready-made product that can be simply customized for your WorkFlow, why is there testing?
Salesforce has hidden its database so deep that preparing some data for testing will be a nightmare.
And now, after 9 months on the project, I share my thoughts, ideas and pain about the possibilities and approaches to automating Salesforce testing.
Salesforce was once a SaaS CRM. Over the course of time, the platform absorbed all sorts of organizations, began to provide the ability to develop applications on its own base using the PaaS model. Recently, the platform has gone deep into analytics, BI and marketing, mainly through acquisitions of companies like Buddy Media and Tableau (bought, by the way, this year for about $ 16 billion).
At the moment, Salesforce, in addition to setting up those very WorkFlow, has its own programming language called Apex. The language is strongly typed, object-oriented, the syntax is very similar to Java. Here are some cool Apex and Salesforce knowledge for automators:
- The syntax is clear, built in essence on triggers, object descriptions and database queries;
- Unit tests can be written on Apex. Salesforce requires developers to have at least 75% test coverage. Otherwise, the build will not be successful;
- JS and layout are still needed, but most pages can be built from a constructor provided by Salesforce itself (i.e. there is practically no need to test the UI, since one field does not differ from the second, which simply has a different name);
- You cannot access the database via JDBC. But for each object in the system, a REST API with a full CRUD is automatically generated.
Test Automation Approach
So, we have code coverage by default > 75%. We have a UI, which in most cases is not written by developers, but is composed of standard components. Testing is necessary, in fact, at the level of business logic and interactions between different UI components and trigger calls. In fact, in order to competently build a testing pyramid, we need to add ~ 20-25% of tests for the REST API and another ~ 5-10% for the UI. The UI for almost any object in Salesforce consists of the following pages.
PageObjects, accordingly, describe some forms. In Salesforce, developers can create forms in three ways, the locators for the fields on them, respectively, will be different:
- Formerly relevant Visualforce forms: https://help.salesforce.com/articleView?id=pages_custom_components.htm&type=5
- Standard Salesforce forms thrown through the designer;
- Stylish, trendy, youthful Lightning forms: https://developer.salesforce.com/docs/component-library/overview/components
Next, let’s look at the types of fields that may be present on these forms. If we analyze the most commonly used ones, then these are:
- Input (VisualforceInput.java, SalesforceInput.java, LightningInput.java);
- TextArea (VisualforceTextArea.java, SalesforceTextArea.java, LightningTextArea.java);
- Select (VisualforceSelect.java, SalesforceSelect.java, LightningSelect.java);
- MultiSelect (VisualforceMultiSelect.java, SalesforceMultiSelect.java, LightningMultiSelect.java).
In theory, locators can have an “OR” logic inside them, and then you can get away from 3 classes for different technologies.
As a result, each of the 3 PageObjects listed above should consist of fields of the corresponding types, which differ only in name. The entire internal kitchen for the search locator is inside the wrapper under the element. Having such a base of a mass of pages and fields, you can collect any tests for CRUD operations within Salesforce for them. Our Build Verification Test consists of such CRUD operations. To test more complex logic, a lot of initial conditions are prepared, all of them are prepared to the maximum through the REST API. We’ll talk about how to interact with the Salesforce REST API in another article, but for now let’s discuss what problems we eventually had to face during automation:
- Salesforce allows users to work in different tabs within the app. As a result, locators are solid XPATHs, where at the beginning there is a prefix for the current active tab, then only the locator itself;
- Salesforce allows you to login without two-factor authentication only with “Trusted IPs”. As workarounds: disable such authentication, receive session cookies and substitute them in the driver, add all IPs as trusted to the Git repository so that the settings do not get lost after each application deployment. Or use the plugin for Chrome, which in a couple of seconds will add all IPs to the configs of your organization with handles: https://chrome.google.com/webstore/detail/whitelist-all-ips-for-sal/nnlnikmkbpgioojghgojoejgcheilic
- Big amount of Roles / Profiles and Permission Sets within the organization, as well as the inability to create users on the fly through, say, the REST API leads to a rather monotonous preparation of test data after copying data from the production server to the server for autotests (if, of course, you need prod-like data).
In the end, I want to say that on the Internet, there was no ready-made framework for the tasks described above. As a result, our own was created by ElmoSoft: it will be discussed in subsequent articles.