Automating LWC Testing with Jest: A Simple Guide for Developers

Lightning Web Components Automating LWC Testing with Jest Salesforce Shastras

Introduction

Testing is a crucial part of the software development process. It ensures that your code works as expected and helps prevent bugs from making it to production. In the world of Salesforce, Lightning Web Components (LWC) are a key part of the development process, and Jest is a popular testing framework that can help automate the testing of these components, In this blog we will see how we can Automating LWC Testing with Jest.

Step 1: Prerequisites

Before you begin, make sure you have the following installed and updated:

  • Salesforce CLI
  • Visual Studio Code
  • Salesforce Extensions for Visual Studio Code

Step 2: Create a Salesforce DX Project

In Visual Studio Code, open the Command Palette by pressing Ctrl+Shift+P (Windows) or Cmd+Shift+P (macOS). Enter sfdx. Select SFDX: Create Project. Select Standard. Enter test-lwc as the project name. Press Enter. Select a folder to store the project. Click Create Project and wait for the new Visual Studio Code window to open.

Step 3: Install Node.js and npm

Jest is a Node module, so to use it you need to install Node.js and npm. Install Node.js from the official Node.js website. We recommend using the LTS (long-term support) version.

Confirm Node.js is installed by entering the following command in the terminal: node --version. When you install Node.js, npm also installs automatically. In a terminal, enter the following command to confirm npm is installed: npm --version.

Step 4: Install the @salesforce/sfdx-lwc-jest JavaScript module

This module is used to run Jest against Lightning web components in a Salesforce DX workspace environment. To install it, use the following command: yarn add -D @salesforce/sfdx-lwc-jest@winter22 or yarn add -D @salesforce/sfdx-lwc-jest@spring22.

Step 5: Writing Your First Test

Now that you have Jest installed, you can start writing tests. Create a new file with a .test.js extension. For example, if you’re testing a component called myComponent, you would create a file called myComponent.test.js.

Here’s an example of what a simple test might look like:

import { createElement } from 'lwc';
import MyComponent from 'c/myComponent';

describe('c-my-component', () => {
    afterEach(() => {
        // The jsdom instance is shared across test cases in a single file so reset the DOM
        while(document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }
    });

    it('displays the correct label', () => {
        // Create element
        const element = createElement('c-my-component', {
            is: MyComponent
        });
        document.body.appendChild(element);

        // Verify displayed greeting
        const div = element.shadowRoot.querySelector('div');
        expect(div.textContent).toBe('Hello, World!');
    });
});

In this test, we’re importing the myComponent component, creating an instance of it, adding it to the DOM, and then checking that it displays the correct text.

let’s take a look at a more complex test case. This time, we’ll test a component that takes an input and updates its state accordingly.

import { createElement } from 'lwc';
import MyComponent from 'c/myComponent';

describe('c-my-component', () => {
    afterEach(() => {
        // The jsdom instance is shared across test cases in a single file so reset the DOM
        while(document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }
    });

    it('updates the message when the input changes', () => {
        // Create element
        const element = createElement('c-my-component', {
            is: MyComponent
        });
        document.body.appendChild(element);

        // Select input for simulating user input
        const inputElement = element.shadowRoot.querySelector('lightning-input');
        
        // Simulate user input
        inputElement.value = 'Jest is great!';
        inputElement.dispatchEvent(new CustomEvent('change'));

        // Return a promise to wait for any asynchronous DOM updates
        return Promise.resolve().then(() => {
            // Query for the paragraph element that displays the message
            const pElement = element.shadowRoot.querySelector('p');
            
            // Verify that the input value is reflected in the paragraph element
            expect(pElement.textContent).toBe('Jest is great!');
        });
    });
});

Here’s what each part of the code does:

  • import { createElement } from 'lwc'; and import MyComponent from 'c/myComponent';: These lines import the necessary modules and the component that you want to test.
  • describe('c-my-component', () => {...});: This function defines a block of tests for the myComponent component.
  • afterEach(() => {...});: This function runs after each test. It’s used here to clean up the DOM after each test.
  • it('updates the message when the input changes', () => {...});: This function defines an individual test. In this case, the test checks whether the component correctly updates its message when the input changes.
  • const element = createElement('c-my-component', {is: MyComponent});: This line creates a new instance of the myComponent component.
  • document.body.appendChild(element);: This line adds the new component instance to the DOM.
  • const inputElement = element.shadowRoot.querySelector('lightning-input');: This line selects the input element within the component.
  • inputElement.value = 'Jest is great!'; and inputElement.dispatchEvent(new CustomEvent('change'));: These lines simulate a user typing ‘Jest is great!’ into the input element.
  • return Promise.resolve().then(() => {...});: This line returns a promise that resolves after all the asynchronous tasks in the test have completed.
  • const pElement = element.shadowRoot.querySelector('p');: This line selects the paragraph element that displays the message.
  • expect(pElement.textContent).toBe('Jest is great!');: This line checks that the paragraph element’s text content matches the input string.

Step 6: Running Your Tests

To run the test, you can use the Salesforce CLI by executing the following command: npm run test:unit.

Conclusion

Automating your LWC tests with Jest can help you catch bugs early, make your code more robust, and speed up your development process. While this guide provides a basic introduction to using Jest with LWC, there’s a lot more to learn. Be sure to check out the official Jest documentation for more information.

Additional Resources: Test Lightning Web Components

Leave a Reply

Your email address will not be published. Required fields are marked *