小程式自動化測試的wx API攔截

2020-11-13 21:01:19

欄目小程式自動化測試的wx API攔截。

隨著小程式越來越被廣泛使用,我們前端的開發工作也從單純的web開發,擴大到web+小程式的跨端開發。為了提高研發效率,越來越多的web模組需要遷移、更新,相容小程式以實現跨端複用。而這些模組也會跟隨業務進行迭代和版本更新,這時候,我們就需要有良好的測試來保障各端模組的可靠性。

由於我們將許多已有的web模組遷移到小程式,web端的測試相對已經比較完備了。因此我們需要考慮的是:

  1. 如何快速的將已有的web用例遷移到小程式

  2. 針對新模組,如何快速編寫兩端用例

(我們在web端使用的主要是Puppeteer和Jest的搭配。)

可直接移步最終方案

測試模組型別

我們目前的模組主要是以下三種型別:

  1. 與環境無關的邏輯層模組
  2. 與環境關聯的邏輯層模組
  3. 與環境關聯的UI元件模組

型別1的模組由於不受環境限制,可與web共用單元測試,無需額外的測試用例開發。

型別3的模組,由於小程式與web端差異較大,比較難實現複用(目前我們的web UI層主要基於React,小程式使用原生開發,同時配合kbone進行部分頁面的同構開發)。

我們這裡主要針對型別2的模組進行測試用例的遷移。

小程式端測試工具選擇

小程式官方目前提供了兩種工具來支援小程式測試:

  1. 元件單元測試 提供了一個測試工具集以支援自定義元件在 nodejs 單執行緒中執行。
  2. 小程式自動化 為開發者提供了一套通過外部指令碼操控小程式的方案。

通過官方工具結合Jest, Mocha等測試框架,我們可以實現在小程式環境下的測試。

我們選擇了小程式自動化。類似於在Puppeteer執行web端的測試,我們可以通過小程式自動化,操控開發者工具,以實現小程式環境下的測試。兩者的相似之處給我們實現測試用例的跨端遷移甚至複用提供了可能性。

如何遷移測試用例

以遷移一個上報模組的測試用例為例,如下是我們已有的一個web上報模組測試用例。

web測試用例

該用例覆蓋的路徑為:呼叫imlog.default.error()方法 -> 瀏覽器將發起請求 -> 對請求引數進行校驗

test('.error()呼叫正常', async done => {  const opts = {    project: 'imlogtest',
  };  // 檢查上報請求的引數
  const expector = req => {    try {      const url = req.url();      const method = req.method();      const headers = req.headers();      const body = req.postData();      const data = JSON.parse(body);

      expect(url).toBe(DEFAULT_URL); // 請求的url符合預期
      expect(method).toBe('POST'); // 請求的method符合預期
      expect(headers['content-type']).toBe('text/plain'); // 請求的contentType符合預期
      expect(data.url).toBe(TEST_PAGE_URL); // 請求體的url欄位符合預期

      done();
    } catch(error) {
      done(error);
    }
  };  // 監聽上報請求並校驗引數
  page.once('request', expector);  // 在瀏覽器中執行上報
  page.evaluate(    (o) => {      const reportor = window.imlog.default;
      reportor.config(o);
      reportor.error('test'); // 進行上報
    },
    opts
  );
});複製程式碼

以上主要用到了Puppeteer的Page API。

  • page.evaluate 控制頁面執行一段邏輯(執行imlog.default.error())
  • page.once('request', expector) 監聽頁面的請求並獲取引數(檢測是否發起請求並校驗請求引數)

小程式用例的設想

小程式自動化給我們提供了一些類似於puppeteer的API:

  • miniProgram.evaluate 控制小程式往 AppService 注入程式碼片段並返回執行結果

如果小程式能夠像Puppeteer,使用監聽事件的形式攔截到wx API的呼叫引數,測試用例編寫將會方便許多。我們想象的小程式用例將會是如下形式:

test('.error()呼叫正常', async done => {  const opts = {    project: 'imlogtest',
  };  // 檢查上報請求的引數
  const expector = req => {    try {      // diff:按照特定格式解析出小程式請求引數
      const {url, method, headers, body, data} = parseWxReqParams(req); 

      expect(url).toBe(DEFAULT_URL); // 請求的url符合預期
      expect(method).toBe('POST'); // 請求的method符合預期
      expect(headers['content-type']).toBe('text/plain'); // 請求的contentType符合預期
      expect(data.url).toBe(TEST_PAGE_URL); // 請求體的url欄位符合預期

      done();
    } catch(error) {
      done(error);
    }
  };  // 監聽上報請求並校驗引數
  // todo: miniProgram物件支援once/on等事件方法
  miniProgram.once('request', expector);  // 在小程式中執行上報
  miniProgram.evaluate(    (o) => {      // diff: 請求方法掛在小程式app物件上
      const reportor = getApp().imlog.default;
      reportor.config(o);
      reportor.error('test'); // 進行上報
    },
    opts
  );
});複製程式碼

只要我們尋找一種方式,通過事件的形式,以miniProgram.on('api', fn)的方式監聽到呼叫API時傳遞的引數。

在這種形式下,web和小程式用例的差異僅在於:

  1. web中page物件的操作轉移到小程式miniProgram物件完成
  2. web中掛載在window下的方法,小程式中掛載在app下
  3. web和小程式解析請求引數的方式不同

wx API攔截方法

首先觀察miniProgram物件,通過miniprogram-automator暴露出來的MiniProgram.d.ts,可以發現MiniProgram類本身就繼承自EventEmitter。

import { EventEmitter } from 'events';export default class MiniProgram extends EventEmitter {  // ...}複製程式碼

接下來就需要尋找方法,在api呼叫時觸發miniProgram物件的emit方法。

有兩個自動化API可以幫助我們實現這點。

  • miniProgram.mockWxMethod 允許我們覆蓋 wx 物件上指定方法的呼叫結果。

  • miniProgram.exposeFunction 在 AppService 全域性暴露方法,供小程式側呼叫測試指令碼中的方法。

此時,一個大膽的想法湧上心頭

以上就是小程式自動化測試的wx API攔截的詳細內容,更多請關注TW511.COM其它相關文章!