Test Lightning Web Components
Jest is a powerful tool with rich features for writing JavaScript tests. Use Jest to write unit tests for all of your Lightning web components.
Run Jest tests at the command line or (with some configuration) within your IDE. Jest tests don’t run in a browser or connect to an org, so they run fast. When run in “watch mode” they give you immediate feedback while you’re coding. Jest tests work only with Lightning web components, they don’t work with Aura components.
Write Jest tests to:
The lwc-recipes repo is filled with Jest tests.
Install sfdx-lwc-jest
Install sfdx-lwc-jest and its dependencies into each Salesforce DX project. sfdx-lwc-jest works in Salesforce DX projects only.
Prerequisites
Before installing sfdx-lwc-jest, install Node.js and npm.
Install Jest and Its Dependencies into Your Project with the Salesforce CLI
The simplest way to install Jest and its dependencies is to run the Salesforce CLI command sfdx force:lightning:lwc:test:setup. Run the command from the top-level directory of each Salesforce DX project. This command creates the necessary configuration files and installs the sfdx-lwc-jest package for you.
Install Jest and Its Dependencies Manually
If you work in an environment where you can’t use the Salesforce CLI, you can set up your test dependencies yourself.
To install sfdx-lwc-jest and its dependencies, run these commands once from the top directory of each Salesforce DX project.
npm install
npm install @salesforce/sfdx-lwc-jest --save-dev
By default, an SFDX project includes these script entries in the scripts block of its package.json file. If your project’s file doesn’t include them, add them.
{
...
"scripts": {
...
"test": "npm run test:unit",
"test:unit": "sfdx-lwc-jest",
"test:unit:watch": "sfdx-lwc-jest --watch",
"test:unit:debug": "sfdx-lwc-jest --debug",
"test:unit:coverage": "sfdx-lwc-jest --coverage",
...
},
...
}
Run Jest Tests for Lightning Web Components
Run your unit tests frequently or continuously during component development.
Run Tests from VS Code
If you install Salesforce Extensions for Visual Studio Code, you can run tests, debug them, and watch Jest files from within VS Code. For more information, see Salesforce Extensions for Visual Studio Code.
Run Tests on the Command Line
To run all tests for your project, use the Salesforce CLI command sfdx force:lightning:lwc:test:run from the root folder of your project. Otherwise, run the command that you added to the scripts block of your project’s package.json file when installing Jest and dependencies .
npm run test:unit
Run Tests Continuously During Development
To run all tests for a single component every time you save changes, go to the component directory and run the sfdx-lwc-jest command with the --watch parameter. Use the entry that you added to the scripts block of your project’s package.json file when installing Jest and dependencies.
npm run test:unit:watch
Jest watches all component files for updates, and runs all relevant tests each time it detects a change.
Run Jests Tests in Debug Mode
Running Jest tests in debug mode is useful if you want to step through your tests and app code to find out why your tests or code aren't behaving as expected. You can debug Jest tests using the following tools.
The VS Code Salesforce Extension Pack provides the simplest and most straightforward option, while Chrome DevTools caters to seasoned web developers. The advanced configuration for the VS Code debugger also enables you to work with different debuggers and debugging scenarios. The advanced configuration offers the most flexible option for debugging your Jest tests.
For more information, see Debug Jest Tests for Lightning Web Components.
Advanced Jest Configurations
sfdx-lwc-jest is configured to run Jest tests without any additional changes. However, if you’re an advanced Jest user, check out some of Jest's other configuration options. See github.com/salesforce/sfdx-lwc-jest#overriding-jest-config.
If your Jest tests are executing slowly and they have dependencies from different folders, provide mappings to speed up the resolution. See the moduleNameMapper in the lwc-recipes repo.
Write your component tests in local JavaScript files. Commit them to version control along with the component itself. Jest tests aren’t saved to Salesforce.
Recommended by LinkedIn
Components use the wire service to get data from Salesforce. To test how these components handle data and errors from the wire service, use the @salesforce/sfdx-lwc-jest test utility.
DOM Inspection Tests Are Subject to Change
The content and structure of HTML, CSS, and the DOM in Lightning Experience can change at any time and can’t be considered a stable API. UI tests thusing tools like Selenium WebDriver to reach into component internals require going maintenance.
Salesforce has never guaranteed backward-compatible HTML, CSS, or DOM. We’re calling out the fragility of these tests due to changes as Lightning Experience continues to evolve with modern web standards. We understand the value that you gain from automated UI testing, and the maintenance burden this puts on you.
Lightning web components are based on the Web Components standard. This standard includes Shadow DOM, which hides a component's markup, style, and behavior from other components. This encapsulation poses challenges for UI tests, especially tests that rely on globally searching the DOM or reaching into the internals of custom elements.
The shadowRoot property encapsulates an element's DOM subtree. This shadowRoot is represented as a DocumentFragment in the DOM. Elements inside this DOM subtree are not available by traditional DOM querying methods. Elements that are rendered by Lightning web components contain this new shadowRoot property, and these elements are hidden from normal DOM queries.
We recommend using Jest to unit test individual Lightning web components.
Use UI testing tools like Selenium WebDriver only for end-to-end testing.
Jest Tests
To write unit tests for Lightning web components, use sfdx-lwc-jest.
In a Jest test context, code can use the shadowRoot property of the element under test to access the shadow tree. The shadowRoot property encapsulates an element’s shadow tree.
This code accesses the <div> in the shadow tree of the <lightning-lwc-parent> component in the Example section.
const element = createElement('c-lightning-lwc-parent', { is: LightningLwcParent });
document.body.appendChild(element);
const div = element.shadowRoot.querySelector('.in-the-shadow');
Selenium WebDriver Tests
For end-to-end UI tests, adapt your existing tests for Shadow DOM use. Adapting your tests varies by tool, and strategies are rapidly evolving. This article is a good example for Selenium WebDriver.
As the article discusses, global queries via WebDriver.findElement() fail. To look for an element inside a Lightning web component’s shadow tree, execute JavaScript on the client to query off the component’s shadowRoot property.
The article has a screenshot that shows DOM elements in Chrome Developer Tools. The screenshot shows a #shadow-root document fragment, which is the top node of a component’s shadow tree. If you look at a Lightning web component in Chrome Developer Tools, you don’t see the #shadow-root because LWC uses a shadow DOM polyfill.
Salesforce supports some browsers that don’t implement the Shadow DOM web standard. The polyfill provides a shadow DOM in these browsers. To find Lightning web components on the page, look for element names that contain a hyphen. Select the element and run $0.shadowRoot in the Console. A Lightning web component returns #document-fragment.
While testing with Jest, follow these patterns and practices to isolate behavior and maximize the efficiency of your unit tests.
Test a Property Change
Let’s start by looking at a simple property change. Component rerendering upon a property change is asynchronous, so the order in which something is added to the DOM isn’t always predictable. We recommend that your test waits for a value change to be reflected in the DOM before checking for the expected behavior.
One technique uses a Promise.resolve() statement to check the value after the page element changes, as follows:
it('Renders with Hello Matt', () => {
const element = createElement('c-hello-component', {
is: HelloComponent,
});
document.body.appendChild(element);
element.person = "Matt";
return Promise.resolve().then(() => {
const pTag = element.shadowRoot.querySelector('p');
expect(pTag.textContent).toEqual('Hello, Matt!');
});
});
Test a Component with Attributes
To expand on our example, let’s add an attribute. Attributes let you change one value in a test to see how a change renders. Use a Object.assign() statement to set an attribute before the appendChild call like:
Object.assign(element, attributes);
document.body.appendChild(element);
For example, let’s set the background color in our initial test to red:
it('Renders with Hello Matt', () => {
const element = createElement('c-hello-component', {
is: HelloComponent,
});
Object.assign(component, { backgroundColor: 'red' });
document.body.appendChild(element);
element.person = "Matt";
return Promise.resolve().then(() => {
const pTag = element.shadowRoot.querySelector('p');
expect(pTag.textContent).toEqual('Hello, Matt!');
});
});
Mocking
Your unit testing likely involves more than just an update to a simple UI element. Some code is dependent upon the behavior of certain dependencies, such as imported modules, base Lightning components, and event handlers. But, you want your code to be in a consistent environment, free from variable behavior and timing of server calls, database requests, or remote access API. The following sections include guidance on mocking the behavior of these dependencies for unit testing. Mocking is a common testing practice that isolates the behavior of the code you’re testing.