Get Started with Testing
Learning Objectives
After completing this unit, you’ll be able to:
- Describe the purpose and differences between unit testing and end-to-end testing.
- Explain the role of unit tests for Lightning Web Components.
Prerequisites
In this module, you develop Lightning web components and unit tests within a Salesforce DX project using the Visual Studio Code editor. If you are unfamiliar with Lightning Web Components, Salesforce DX, or using Visual Studio Code for Salesforce development, we recommend that you complete the Quick Start: Salesforce DX, Quick Start: Visual Studio Code for Salesforce Development, and Quick Start: Lightning Web Components projects before you go on.
Why Testing Is Important
“Any bug not detected in the design phase will cost ten times more time to detect at the coding phase and an additional ten times more at the debugging phase.”
—Dr. Nikolai Bezroukov, The Art of Debugging
Debugging and testing are related but distinct processes in software development. Testing attempts to find and report errors. Debugging attempts to identify the cause of those errors and fix them. And according to Dr. Nikolai Bezroukov, when finding and squashing bugs in your code, the earlier the better.
In an ideal world, software wouldn’t have any bugs. But the reality is, we make mistakes, requirements get misunderstood, and applications get used in ways that were never anticipated. Testing helps uncover these issues so they can be fixed. The earlier you find bugs, the “cheaper” they are. Once bugs hit the next stages of development (or in the worst case, production) more people and processes get involved to identify and fix them.
There are two types of tests that are commonly performed for Salesforce applications: unit tests and end-to-end tests. Their differences are in their scope and purpose.
Unit Testing
Unit testing focuses on testing small, discrete pieces of functionality in an application. To facilitate unit testing, build your application using small, testable units, instead of writing a single long Apex method or class. This means modularizing the code into discrete methods that can be tested independently. Likewise, rather than writing a single massive Lightning component for an application, modularize the features into smaller components that can be tested independently. Short, fast unit tests that are easy to run encourage developers to write and run them as part of their development and continuous integration process. This ensures bugs are identified and fixed sooner rather than later. Be sure to check out test-driven development (TDD) for more insight into this process.
End-to-End Testing
End-to-end tests focus on testing an entire application or user journey. For web applications, this often involves testing in a browser to validate how the code and components on a page work together in a test environment, such as a sandbox or a scratch org.
End-to-end tests tend to be slower than unit tests because they cover more functionality of the application per test. End-to-end tests are also less reliable than unit tests because of the random inconsistencies of a live environment, such as network latency, caching, dependency on third-party systems, infrastructure issues, and so on. These inconsistencies can cause a test to pass one time and fail the next, known as a flapping test. Despite these drawbacks, end-to-end tests provide a valuable, more realistic validation of the application and its integration points than unit tests.
Unit Testing vs. End-to-End Testing
Let’s take a look at how unit testing and end-to-end testing work in practice. As an example, we’ll use the api-property Lightning web component from the lwc-recipes repo, a collection of code examples for Lightning Web Components on the Salesforce platform.
The <c-api-property>
component consists of (1) <lightning-card>
, (2) <lightning-input>
, and (3) <c-chart-bar>
components.
- The
<lightning-card>
component displays the ApiProperty title and contains the other two components. - The
<lightning-input>
component handles the user input of a number and broadcasts value change events. - The
<c-chart-bar>
component renders a bar chart based on its percentage value.
Each of these three components has its own public API, internal state, and behavior. And each of these components could have their own unit tests to validate their functionality in isolation of the other components. In fact, the unit tests for the <c-api-property>
component can assume that the <lightning-card>
, <lightning-input>
, and <c-chart-bar>
components will perform as expected, or it can mock their behaviors to simulate different scenarios under various conditions.
In this example, an end-to-end test would load the <c-api-property>
component in a browser page, enter percentage values into the input field, and assert the bar chart renders accordingly. As an end-to-end test, there is no mocking of data or behaviors—you are confirming how all three components work together as they would when deployed to your users.
Summary
The following table is a high-level comparison of the pros and cons of unit testing and end-to-end testing.
|
Unit Testing |
End-to-End Testing |
---|---|---|
Tests run fast |
Yes |
No |
Tests are reliable |
Yes |
No |
Tests are precise and allow you to identify exact problems |
Yes |
No |
Tests cover many features of an application at once |
No |
Yes |
Simulates a real user |
No |
Yes |
Now that you know more about the differences between unit testing and end-to-end testing, let’s see how it’s done in practice. The rest of this module focuses on unit testing Lightning web components.
Resources
- Developer Guide: Lightning Web Components
- Trailhead: Build Lightning Web Components
- Trailhead: Unit Testing on the Lightning Platform
- External Site: Google Testing Blog: Just Say No to More End-to-End Tests
- External Site: Kent Dodd’s Blog: Write Tests
- External Site: Simple Programmer: Back to Basics: Why Unit Testing is Hard
- External Site: Wikipedia: Test-Driven Development