論如何進行小程式自定義元件的單元測試
前言
自從小程式自定義元件和 npm 功能面世之後,元件化和開源思想逐步開始萌芽了。我們可以將一些通用的部件,如自定義導航欄之類的封裝到一個自定義元件中,然後藉由 npm 平臺開源出去給其他開發者使用,這樣可以省去很多勞動。相信各位開發老爺們應該或多或少都有過使用開源包的經歷,但是在使用前,這個開源包得能贏取我們的信任,一個很重要的指標就是單元測試通過率和覆蓋率。
但是因為小程式獨特的執行環境和不完全開源的基礎款,使得對小程式自定義元件的單元測試稍微有點困難。目前市面上無論是 vue 還是 react,這些元件化框架都有一套完善的單元測試解決方案,但是對於小程式自定義元件來說卻寥寥無幾,因此這個工具集——
痛點
閒話不多說,我們先看下小程式的執行機制:
可以看出,小程式自定義元件是渲染與邏輯脫離,想在邏輯層拿到渲染的結果進而進行對比測試是很難辦到的。而且目前小程式的環境並不開放,想要完整構造模擬出小程式的執行環境也不太科學。另外我們這邊只是需要對小程式的自定義元件做單元測試,對於小程式中很多非自定義元件相關的功能可以不考慮,而且在效能上也不那麼苛求,所以一個思路是調整底層執行機制,將雙執行緒合併為一個執行緒,將 wxml、wxss 的解析器改成純 js 實現。
實現
只是有思路還不夠,在實現過程中還是有一些坎的。比如要如何比較好的模擬出小程式自定義元件的各種特性和功能呢?自己實現也不是不行,問題在於維護的成本,如果小程式自定義元件實現了一個功能,測試工具還得更新一下。另外如果在實現上略有差池的話,可能小程式端的一個小調整對於測試工具都可能是傷筋動骨式的改造。所以這裡直接將小程式自定義元件的最核心模組—— exparser 從基礎庫中抽離出來。
exparser 是自定義元件系統的核心,是一個完整獨立的模組,不依賴於基礎庫中其他模組。它完全脫離於小程式的 api 和執行機制體系,所以無論是單執行緒還是雙執行緒機制都可以使用。exparser 提供的是自定義元件系統最底層的介面,測試工具將其進行二次封裝成自定義元件測試環境。如果基礎庫有關於自定義元件的更新,如果是底層改造,則直接更新 exparser 模組即可;如果只是外層改造,那基本上是暴露介面層面的調整,也不必作太多大範圍的調整。
PS:目前雖然 exparser 已經發布到 npm,但是仍然只是混淆壓縮後到程式碼,屬於半開源狀態,不建議開發者直接使用。
使用
下述只簡單介紹下用法,首先安裝此工具集:
npm install --save-dev miniprogram-simulate
複製程式碼
然後此工具集必須搭配其他測試框架和 jsdom 來使用,比如 jest。因為 jest 內建有 jsdom,所以也就不需要額外安裝 jsdom 了,以下面一個自定義元件作為例子:
<!-- 自定義元件:comp.wxml -->
<view class="index">{{prop}}</view>
複製程式碼
/* 自定義元件:comp.wxss */
.index {
color: green;
}
複製程式碼
// 自定義元件 comp.js
Component({
properties: {
prop: {
type: String,
value: 'index.properties'
},
},
})
複製程式碼
這是一個極其簡單的自定義元件,然後我們在 comp.test.js 裡這樣編寫測試用例:
// 自定義元件 comp 的測試用例:comp.test.js
const path = require('path')
const simulate = require('miniprogram-simulate')
test('comp', () => {
const id = simulate.load(path.join(__dirname, './comp')) // 此處必須傳入絕對路徑
const comp = simulate.render(id) // 渲染成自定義元件樹例項
const parent = document.createElement('parent-wrapper') // 建立父親節點
comp.attach(parent) // attach 到父親節點上,此時會觸發自定義元件的 attached 鉤子
expect(comp.querySelector('.index').dom.innerHTML).toBe('index.properties') // 測試渲染結果
})
複製程式碼
使用方式很簡單,本文只是個引子,更多詳細的用法請移步到 github 倉庫上查閱。
尾聲
要想判斷一個自定義元件的質量如何,其中最簡單的方法就是看單元測試的表現,想要別人使用你的自定義元件,質量把關很重要,目前 miniprogram-simulate 已經實現了最基本的功能,其他功能也在盡力施工中,有什麼好的建議或者使用上遇到什麼問題也可以提 issue。如果好評請 star 噢~