小程序測試方案初探

前言

2017年1月9號微信小程序正式上線,小程序不須要安裝就能使用,依託微信強大的生態環境,能作到不少H5所不能作的事情。從微信小程序發佈這段時間,陸陸續續開發了很多小程序相關的項目,總結了一些通用性的組件,可是對於小程序如何作測試,依然是一頭霧水,直到作了很多的項目,積累的一些經驗和開源庫以後才理清如何作測試,下面將會介紹如何對小程序作UI測試和單元測試。javascript

工具的準備

介紹

node
這個應該不用多作介紹了,不過此次demo中要求node版本應該大於7.6.0,由於puppeteer要求最低版本是v6.4.0,可是由於官方示例中大量使用 async/await 等新特性,因此須要使用 v7.6.0 或更高版本的 Node,async/await能讓異步回調代碼更加簡潔,否則整個代碼都是promise.then前端

puppeteer
Chrome 團隊出品的一款更友好的Headless Chrome Node API,用於代替用戶在頁面上面點擊、拖拽、輸入等多種操做,常見的使用場景仍是應用到UI自動化測試,puppeteer能夠對頁面進行截圖保存爲圖片或者PDF,解決爬蟲沒法實現的一些操做(異步加載頁面內容) 。java

相似的工具:
phantomjs
seleniumhq
nightmarenode

wept
wept可讓小程序脫離開發者工具或者微信客戶端直接運行在瀏覽器上面,後臺使用node,提供小程序API的模擬返回(wx.login、wx.getUserInfo等),前端實現了 view 層、service 層和控制層之間的相關通信邏輯。git

mocha
JavaScript測試框架,在瀏覽器和Node環境均可以使用,經過測試框架,能夠爲你的JavaScript代碼添加相應的測試用例,使得項目代碼更增強健。github

chai
Chai是一個BDD/TDD模式的斷言庫,在node和瀏覽器環境都能運行,API通俗易懂,斷言類型和方式豐富,搭配mocha,江湖人戲稱爲"抹茶"chrome

配置環境

npm i -g wept
npm i --save-dev puppeteer mocha chainpm

在安裝puppeteer有可能會出現如下報錯小程序

ERROR: Failed to download Chromium r508693! Set "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" env variable to skip download.
Error: Download failed: server returned code 502. URL: https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/508693/chrome-win32.zip
    at ClientRequest.https.get.response (D:\chromium\node_modules\puppeteer\utils\ChromiumDownloader.js:197:21)
    at Object.onceWrapper (events.js:316:30)
    at emitOne (events.js:115:13)
    at ClientRequest.emit (events.js:210:7)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:565:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:116:23)
    at Socket.socketOnData (_http_client.js:454:20)
    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at ClientRequest.onsocket (D:\chromium\node_modules\https-proxy-agent\index.js:181:14)

實際上是由於下載完puppeteer包以後有執行node install.js去下載chromium(實驗版chrome),可是因爲網絡的緣由,下載失敗了,咱們能夠避免缺省的下載 chromium,經過設置環境變量來阻止set PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
而後手動去下載chromium,上面有給出連接https://storage.googleapis.co...微信小程序

TODO

直接看官方給出的demo

const puppeteer = require('puppeteer');
(async () => {
  //這裏和官方不同的就是,須要手動指定chromium目錄所在的地址(上面連接下載以後解壓),headless爲true則不會打開chromium
  const browser = await puppeteer.launch({executablePath: '/chromium/chrome.exe',headless: false});
  
  //至關於新建選項卡
  const page = await browser.newPage();
  //跳轉到指定URL
  await page.goto('https://example.com');
  //截圖
  await page.screenshot({path: 'example.png'});
  //關閉頁面或者選項卡
  await browser.close();
})();

上面幾行代碼其實就是至關於咱們平常的一些操做:打開chrome->新建選項卡->輸入url並回車->頁面截圖->保存,也能夠看出puppeteer是站在使用者的角度去設計API。

跑通測試demo以後,來試試小程序這邊,首先必須讓小程序跑在chrome上面,就要用到wept了。
1. 直接在小程序根目錄上面執行wept
而後打開chrome,訪問http://localhost:3000/#!pages/index/index ,就能夠看到小程序運行在chrome上了,接下來要讓puppeteer去抓取小程序裏面的內容,直接上代碼

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
(async () => {
        const browser = await puppeteer.launch({executablePath: '/chromium/chrome.exe',headless: true});
        const page = await browser.newPage();
        //設置展現的設備https://github.com/GoogleChrome/puppeteer/blob/master/DeviceDescriptors.js
        await page.emulate(devices['iPhone 6']);
        //多一個參數waitUntil,指跳轉以後等待網絡空閒以後再執行下一步操做,沒有這個的話,截圖頗有多是白屏,由於內容還沒渲染出來
        await page.goto('http://localhost:3000/#!pages/index/index', {waitUntil: 'networkidle'});
        //小程序的內容實際上是放在一個iframe裏面,外面是沒法直接抓取到iframe裏面的內容,因此這裏須要獲取頁面全部的iframe
        const frames = await page.frames();
        //根據iframe的name屬性來獲取正確的iframe
        const weChatFrame = frames.find(f => f.name() === 'view-0');
        //在上下文環境中獲取須要抓取的內容
        const outerText = await weChatFrame.evaluate(() => {
        //上下文執行環境,跟H5一致
            const anchors = Array.from(document.querySelectorAll('.container'));
            return anchors.map(anchor => anchor.textContent);
        });
        console.log('the outerText: ', outerText);
        await browser.close();

})();

直接來看頁面執行的效果
圖片描述

這樣咱們就能拿到小程序的內容,便於咱們後續的單元測試,接下來咱們能夠加入"抹茶"來測試輸出是否符合預期,先上代碼

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const expect = require('chai').expect;
describe('output test', () => {
    it('should return Hello 測試賬號 ', () => {
        (async () => {
            //小程序內容獲取代碼跟上述一致
            //...
            expect(outerText[0]).to.equal('Hello 測試賬號');
            //...
        })
    })
})

運行效果
圖片描述

結語

小程序其實也有上線一個雲測試,可是我以爲有個很差的地方,假如你的小程序是依賴於後臺CGI返回數據做爲展現,那麼你必須先上線CGI才能使用雲測試,不夠靈活,更但願有一個能本身mock數據來測試不一樣狀況下的小程序的展現。

本篇文章介紹使用wept和puppeteer來對小程序作E2E測試,對於測試環境和正式環境仍是有差別的,好比Object.defineProperty小程序是不支持這個API的,可是測試環境是能夠跑通的,固然測試環境下面也能夠經過某種方式(好比delete)來禁用不支持小程序的API,從而達到測試環境儘量的貼近小程序的正式環境。固然更但願的是小程序官方能給出相應的單元測試方案吧。

相關文章
相關標籤/搜索