Salesforce LWC學習(二十五) Jest Test

zero.zhang發表於2020-09-12

本篇參看: 

https://trailhead.salesforce.com/content/learn/modules/test-lightning-web-components

https://jestjs.io/docs/en/expect

我們在寫lwc的js部分時,通常都是前端進行測試,針對js測試其實也有類似於apex class中的 test class類似的js test class,也就是今天說的 Jest Test,Jest Test不只是針對於 lwc可以使用,正常其他的非salesforce的javascript程式碼同樣可以進行使用測試,所以本篇 Jest Test使用只是基於最簡單的方式去講解,深入學習還要看篇頭的兩個連結自行學習。vs code studio使用 Jest Test步驟如下:

一. 安裝node.js以及npm

因為jest是node的一個模組,所以想使用jest功能需要先安裝node.js,當正確安裝完node.js以後,npm也會自動安裝完成。node下載地址為:https://nodejs.org/en/download/,我們選擇一個需要的版本進行下載安裝即可,官方建議LTS 版本。

安裝好以後輸入 node --version 以及 npm --version以後,正確展示版本資訊即證明已經安裝成功。

 二. 安裝 sfdx-lwc-jest 模組

這裡有多種方式可以安裝,通過CLI的指令:sfdx force:lightning:lwc:test:setup 或者通過npm安裝也可以: npm install & npm install @salesforce/sfdx-lwc-jest --save-dev。這裡demo使用第二種方式

 三. jest 語法實現

jest語法根據不同的js內容複雜度以及難易程度不同,篇頭連結為官方文件包含了各種場景,下面只是講一個最基礎的官方的demo來拋磚引玉。

先展示一下模組的層級結構,我們建立了一個lwc的模組,除了 __tests__這個目錄,想必大家都很熟悉,包含自動生成的三個檔案以及自己建立的一個 sum.js,這個js用於 unitTest.js的引用。我們為某個module建立 Jest Test檔案,需要先在這個module下建立一個 __tests__目錄,這個名字儘量寫死成這個,並且我們需要在 .forceIgnore配置 /__tests__/,意思為當上傳程式碼的時候,目錄名稱為 __tests__裡面的檔案將不會部署。所以如果在其他的module中建立的目錄不是 __tests__情況下,還需要在 .forceIgnore中維護相關名稱,為了統合,建議都起這個目錄名稱。

 我們在 sum.js中封裝了一個加和的方法

export function sum(x, y) {
    return x + y;
}

那我們如何對這個js檔案進行寫 jest test進行驗證呢,首先,我們先建立一個在 __tests__目錄下新建一個js檔案,這個js檔案通常按照js名稱後面加.test.js方式建立,比如 sum.js我們對這個js寫 test class新建的js檔名稱可以起名sum.test.js

對程式碼進行分析:

  • import 用來將 函式引入, ../sum原因是 sum.js在__test__同層,所以需要先找到同層以後在引入;
  • describe是jest封裝好的一個API,可以檢視一下此連結:https://jestjs.io/docs/en/api , 此API用於建立一個將幾個測試組合在一起的模組。有兩個引數,第一個引數是測試場景的名稱,可以和方法名相同也可以不同,但是要求看其名知道測試哪個功能,第二個引數是一個函式用來校驗測試情況;
  • it其實代表著test,這個方法我們同樣可以寫成 test(),test的方法詳情檢視:https://jestjs.io/docs/en/api#testname-fn-timeout 。 它也接受2個引數,第一個是描述,儘量通過描述知道要驗證什麼,第二個是函式用來做斷言,還有第三個函式設定超時時間,預設是5秒,作為可選項,不寫也沒有問題;
  • expect我們可以參考下面的連結:https://jestjs.io/docs/en/expect#expectvalue ,expect用於任何時候你想測試一個值,引數通常傳的就是我們要校驗的方法,通常後面和其他的函式一起搭配使用,demo中搭配的是 tobe函式一起用,tobe函式:https://jestjs.io/docs/en/expect#tobevalue
import { sum } from '../sum';
 
describe('sum()', () => {
  it('should add 1 and 2 returning 3', () => {
    expect(sum(1, 2)).toBe(3);
  });
});

我們寫完了應該如何執行呢,jest test是基於本地端執行的,所以很快,在vs code中,我們只要方法中點選run test即可執行當前的方法。想要批量執行所有的jest test也是支援的,trailhead中有具體的描述。

 結果展示

 這個demo過於簡單,但是大概的說了一下 js test時包含幾部分,以及怎麼步驟去進行測試。我們在lwc只有工具類可能有這麼簡單的程式碼,其他的都是 extends LightningElement 或者類似相關的js寫法。這種方式建立 jest test和上面還是有很大區別,接下來進行一下擴充套件,看一下場景的lwc js應該如何寫 jest test。

 unitTest.js:引用 sum.js中的 sum方法,設定給 unitNumber變數

import { LightningElement, api } from 'lwc';
import { sum } from './sum';
  
export default class UnitTest extends LightningElement {
  @api unitNumber = sum(2,3);
}

unitTest.html:簡簡單單的在前端展示這個值

<template>
    <lightning-card title="Unit Status" icon-name="standard:bot">
      <div class="slds-m-around_medium">
        Unit {unitNumber} alive!
      </div>
    </lightning-card>
  </template>

這種情況的 jest test應該按照下面的步驟寫,解析也如下:

  • 引入 createElement固定寫法,這種寫法僅用於 test中;
  • 引入 UnitTest javascript controller,類似上面的引入 sum;
  • describe解釋同上;
  • afterEach是上面沒有的方法,官方的解釋如下:https://jestjs.io/docs/en/api#methods, 用於當檔案中的每個test完成後,執行此函式。這裡是用於執行時重置DOM。有人納悶為啥要重置DOM呢?為什麼上面的不需要呢? 因為jest test執行是不需要基於瀏覽器的,我們在測試這種和頁面互動的js時,下面會進行一些建立元素節點操作,所以當測試完相關以後,我們需要重置之前的DOM資訊,以便不影響其他的test測試。
  • createElement用於建立一個我們組建的例項化物件並分配給元素。因為jest沒有執行在瀏覽器,所以匯入組建方式我們需要使用 createElement;
  • 通過document.body.appendChild將當前組建裝載到DOM中,我們便可以使用 querySelector搜尋到相關的元素內容進行斷言操作。
import { createElement } from 'lwc';
import UnitTest from 'c/unitTest';
  
describe('c-unit-test', () => {
  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 unit status with default unitNumber', () => {
    const element = createElement('c-unit-test', {
      is: UnitTest
    });
    expect(element.unitNumber).toBe(5);
    // Add the element to the jsdom instance
    document.body.appendChild(element);
    // Verify displayed greeting
    const div = element.shadowRoot.querySelector('div');
    expect(div.textContent).toBe('Unit 5 alive!');
  });
});

點選 Run Test以後便可以檢視結果

 總結: Jest Test不止應用在 lwc中,其他正常的 javascript也可以,lwc頂多封裝了一些自己用的方式去擴充套件了操作,大部分斷言驗證操作還是使用標準的Jest,所以小夥伴如果專案中如果需要使用Jest Test來確定javascript的穩定性以及正確性,最好先熟練掌握 Jest Test文件。本篇只是拋磚引玉。篇中有錯誤地方歡迎指出,有不懂歡迎留言。

相關文章