Test Lightning Component(LTS) using Jasmine

With the Time the complexity of your Lightning Components grows, so does the risk of defects when you write them, and of breaking changes when you refactor them. So to make sure that your lightning component is working properly like apex you can Automate the testing of your lightning component which allows you to mitigate those risks and verify that your components work as designed when you first write them and continue to work as expected when you make changes or when their dependencies (the framework, another component, or a JavaScript library they depend on) are updated.

Prequisite:- LTS needs Salesforce DX for installing the Lightning Testing Services Package.

Lightning Testing Services(LTS) uses Jasmine a JavaScript Testing Framework to test the Lightning Component. Below are the Key Concept of Jasmine

  • A test suite is a plain JavaScript file wherein related tests (specs) are organized within describe() functions.
  • A spec (or test) consists of one or more expectations invoked within it() function.
  • An expectation is an assertion that evaluates to either true or false.
  • A spec is passing when all its expectations evaluate to true. A spec is failing when at least one of its expectations evaluates to false.

Step 1:- Create Project in Visual Studio Code using below command

sfdx force:project:create -n Project_Name -x
Where
-n => denotes the name of the project. Replace Project_Name with the name of your Project.
-x => Generates a default manifest (package.xml) for fetching Apex, Visualforce, Lightning web components, Aura components, and static resources.

Step 2: – Authorize DevHub and Create Default Scratch ORG.

Step 3:- Install the Testing Framework using below commands

sfdx force:lightning:test:install

Step 4: – Create a Folder(staticresources) and then Add a JavaScript Static Resource inside that folder.

  • Create a Folder Name “staticresources” inside force-app/main/default/
  • Create a .js file inside the Folder and name it What Ever you want for me I have named it as “myTestSuite“. and below is the Complete Code for .js File
/* it is a very simple test suite */
describe("Lightning Component Testing Examples", function () {
    afterEach( ()=> {
        $T.clearRenderedTestComponents();
    });
    
    describe("A suite that tests the obvious", () => {
        it("spec that verifies that true is true", ()=> {
            expect(true).toBe(true);
        });
    });
});

/* Simple Test Suite for Hello World! */
describe('c:MyLightningComponent', ()=> {
    it('verify component rendering',  (done) => {
        $T.createComponent('c:MyLightningComponent', {}, true)
            .then((cmp) => {
                expect(cmp.find("message").getElement().innerHTML).toBe('Hello World!');
                done();
            }).catch( (e) =>{
                done.fail(e);
            });
    });
});

/* Check the data Binding */
describe('c:componentWithDataBinding', () => {
    it('verify data binding',  (done) => {
       $T.createComponent('c:componentWithDataBinding', {message: 'Hello World!'}, true)
          .then( (component) => {
             expect(component.find("message").getElement().innerHTML).toBe('Hello World!');
             expect(component.find("messageInput").get("v.value")).toBe('Hello World!');
             done();
       }).catch( (e) => {
             done.fail(e);
       });
    });
 });

 /* Check the Method click in Lightning Component */
 describe("c:componentWithMethod", ()=> {
    it('verify method invocation', (done)=> {
        $T.createComponent("c:componentWithMethod", {}, false)
            .then(function (component) {
                expect(component.get("v.counter")).toBe(0);
                component.increment();
                expect(component.get("v.counter")).toBe(1);
                done();
            }).catch(function (e) {
                done.fail(e);
            });
    });
});

/* Test the Application Event */
describe('c:componentListeningToAppEvent',  ()=> {
    it('verify application event',  (done) => {
        $T.createComponent("c:componentListeningToAppEvent",{},false)
            .then(function (component) {
                $T.fireApplicationEvent("c:myAppEvent", {"message": "event fired"});
                expect(component.get("v.message")).toBe("event fired");
                done();
            }).catch(function (e) {
                done.fail(e);
            });
    });
});

/* Test the Server Call from Component */
describe('c:accountListComponent',  ()=> {
    it('verify mocked server method invocation', function (done) {
        $T.createComponent("c:accountListComponent", {}, false)
            .then(function (component) {
                var mockResponse = { 
                    getState: function () { 
                        return "SUCCESS";
                    }, 
                    getReturnValue: function () { 
                        return [{"Name": "Account 1"}, {"Name": "Account 2"}]; 
                    } 
                };
                spyOn($A, "enqueueAction").and.callFake( (action) => {
                    var cb = action.getCallback("SUCCESS");
                    cb.fn.apply(cb.s, [mockResponse]);
                });
                component.loadAccounts();
                expect(component.get("v.accounts").length).toBe(2);
                expect(component.get("v.accounts")[0]['Name']).toContain("Account 1");
                done();
            }).catch( (e)=> {
                done.fail(e);
            });
    });
});
  • Create “YourResource.resource-meta.xml” here replace
    YourResource with the name of your static resource. As My resource is myTestSuite then complete file is myTestSuite.resource-meta.xml.
  • Find the code for myTestSuite.resource-meta.xml file just after the .js FILE
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
    <cacheControl>Private</cacheControl>
    <contentType>application/javascript</contentType>
</StaticResource>

Step 5 :- Start testing the Lightning Components using Jasmine.

Here is the basic example of how we can use LTS.

/* Simple Test Suite for Hello World! */
describe('c:MyLightningComponent', ()=> {
    it('verify component rendering',  (done) => {
        $T.createComponent('c:MyLightningComponent', {}, true)
            .then((cmp) => {
                expect(cmp.find("message").getElement().innerHTML).toBe('Hello World!');
                done();
            }).catch( (e) =>{
                done.fail(e);
            });
    });
});

Explanation: –

  • describe:– A JavaScript function where we can put all test and other desc as well.
  • it:- consists of one or more expectations invoked within it() function.
  • $T.createComponent(component, {objectAttribute}, true) :- createComponent takes 3 Parameters
    • Component:- the name of the Component including nameSpace. For Example, c:HelloWorld
    • Object Attributes:- Attributes that we wanted to send to Component
    • rendered:- True if we wanted to display the output in Application and false if not.

You can get the complete code of the Project that I have Used in my GitHub Repo

https://github.com/amitastreait/Lightning-Testing-Services

References:-

https://developer.salesforce.com/blogs/2018/04/getting-started-with-the-lightning-testing-service.html

Leave a Reply

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