Testing apps is critical to ensure quality and there are different types of tests, such as unit tests, integrations tests, and end-to-end tests. In this post, we’ll focus on automated end-to-end (E2E) tests and present the UI Test Automation Model (UTAM). UTAM is an open source solution built by Salesforce that lets you run E2E tests on any kind of app. We’ll walk you through a practical example with E-Bikes, one of our sample apps.
A brief introduction to end-to-end tests
E2E tests are often performed with an automated UI testing tool, such as WebdriverIO or Selenium. Unlike unit tests, which cover individual components in isolation, E2E tests closely mimic the interactions of business users. E2E tests use a real browser to interact with components and navigate across screens when executing test scenarios.
A key advantage of E2E tests is that they let you test an app even if you do not have full access to its source code. Let’s imagine that you want to test a Salesforce app that integrates with an AppExchange package. You do not have access to the sources of the Lightning Experience or the package. Yet, you can still test the app with E2E tests.
However, this power comes at a cost. An important drawback of E2E tests is that they are known to be fragile and hard to maintain. Whenever a web app changes, so does the DOM. These changes tend to break E2E tests because they are closely coupled with the DOM. In the context of our previous example, an update to the Lightning Experience, such as a new Salesforce release or a new package version, might break your tests.
This maintenance cost is the reason why it’s generally preferable to invest in unit tests as a priority, then integration tests, and finally, E2E tests. There’s a golden software development rule that summarizes it well:
The closer you are to source code, the cheaper it is to find and fix bugs.
With these pros and cons in mind, a Salesforce team came up with a game-changing proposition: the UI Test Automation Model (UTAM).
UTAM addresses the limitations of conventional E2E tests by making them easier to write and maintain. UTAM does not replace a UI testing tool, but it supplements it by decoupling the test code from the DOM thanks to page objects.
You write UTAM page objects in JSON with powerful and easy-to-understand grammar. Page objects are reusable blocks that let you reference the DOM of the page under test with CSS selectors. You can compose page objects to create advanced patterns.
The fact that page objects act as a shareable contract, and they are written in JSON, are major differentiators compared to other UI testing tools. This allows UTAM to work with a mostly language-agnostic approach. In other words, multiple teams can collaborate and share page objects regardless of the technology they use for testing.
Running end-to-end tests with UTAM
Now that we’ve covered what UTAM is and does, let’s look at some practical examples. We’ll start with a small “Hello, world” and show you how to test a real app: the E-Bikes sample app.
Testing a “Hello, world” example
Let’s start with something simple: a “Hello, world” example taken from the great UTAM tutorials. In this example, we’re testing a static HTML page that displays “Hello, 🌍 🌏 🌎!”
Here are the key steps needed to test this page:
- We declare a JSON page object that contains a
worldelement. This element has a
.worldCSS class selector, which matches a DOM element on the page under test.
- We compile our page object, which generates a class with a
getWorldmethod that is tied to the
worldelement that we’ve defined in JSON.
- We use the
getWorldmethod from the compiled page object in our test code to access the content of the DOM with the
While this may seem verbose for a such a simple use case, the power of UTAM becomes obvious when the pages are more complex. In those cases (which are closer to real life apps), composition and reusability are a must have, and UTAM is here to help.
Testing the E-Bikes sample app
UTAM is not limited to testing Salesforce apps; it works with any technology or platform. But Salesforce provides a set of hundreds of reusable UTAM page objects for the base Lightning components (lightning-input, lightning-button, etc.) and the Lightning Experience (see links in resources section). This is a great time saver when writing E2E tests for Salesforce apps. This is why a number of Salesforce engineering teams use UTAM internally to test their apps.
Let’s look at how we run end-to-end tests on the Product Explorer Lightning app page of the E-Bikes sample app.
This page contains a number of standard and custom Lightning Web Components. Accessing the elements of those components by exploring the DOM of the page would be a real challenge without UTAM base page objects because we would have to traverse a number of Shadow DOM layers.
Here’s a diagram that helps to put this into perspective. It presents a simplified view of the nested components that compose this page. Custom components are represented in orange and Lightning base components in blue.
The custom components are unit tested, but our goal is to also run E2E tests to verify user interactions. This is the scenario that we are testing with UTAM:
- Check the default pagination information in the product tile list
- Check that the selected product card is empty by default
- Enter a search term in product filters
- Check the updated pagination information
- Select the first product tile
- Check that the selection is displayed in the product card
- Click on the product card’s button icon to open the product record page
- Ensure that the product record page is open
Before writing the code for the E2E test, the bulk of the effort goes into the definition of the UTAM JSON page objects for the custom components that are part of the test. For the sake of brevity, we won’t cover all of their definitions here, but you can have a look at the E-Bikes GitHub repository. In the folder that holds the metadata of the Lightning Web Components, you’ll find
__utam__ subfolders with the JSON page objects.
For example, this is what the product filter page object looks like and how we retrieve the search input thanks to a Lightning input base page object and a
.search CSS class selector:
Thanks to UTAM, this test code is quite easy to read (it’s not cluttered with boilerplate code or CSS references), and it will likely be stable because it won’t need to updated when the DOM changes (when a CSS class is removed or renamed, for example). Most of the maintenance effort will be focused on the JSON page objects.
We just scratched the surface of what UTAM can do. We saw a refresher on what E2E tests are, what UTAM is, and how it brings added value by decoupling test code from the DOM. Finally, we explored a couple of examples of E2E tests with UTAM. Head over to the UTAM website and take a look at the guide and the great tutorials to learn more advanced concepts, such as dynamic selectors or composition with methods, just to name a few.
- The UTAM website for documentation and tutorials
- UTAM Recipes for a repository full of examples:
- UTAM page objects for Lightning base components:
- E-Bikes sample app repository for an example of end-to-end tests with UTAM
About the author
Philippe Ozil is a Principal Developer Advocate at Salesforce where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full stack developer and enjoys working on DevOps, robotics, and VR projects. Follow him on Twitter @PhilippeOzil or check his GitHub projects @pozil.