曾幾何時,大家還不知道什么是小程序,它到底能干些什么,跟App有啥區別,跟H5又有啥區別,但是最近幾年,依托于騰訊這顆大樹,已經迅速建立起了小程序良好的生態體系,同時也因為APP市場的飽滿,以及其開發和推廣成本高等問題,目前幾乎所有的互聯網公司的業務都用起了小程序,而且頁面也越來越復雜,涉及的業務場景也越來越多,小程序已經是IT互聯網領域一個舉足輕重的屬性了。
為了應對小程序如火如荼的發展,騰訊在今年5月底推出了miniprogram-automator來支持小程序的自動化測試,本文也主要是基于此項技術來做介紹,讓大家對小程序自動化有個初步的了解。
之前小程序自動化的模式
在騰訊推出此項技術之前,其實小程序的自動化測試已經有所開展了,主要有以下幾種方式:
1. 通過APP自動化的工具appium來實現的
2. 通過Airtest來實現
3. 通過FAutoTest來實現
這些方法大同小異,基本上都屬于黑盒自動化方案。此處不做具體介紹,大家可以自行查閱。
純Miniprogram-automator模式
Miniprogram-automator是騰訊自研的一套小程序自動化sdk,原理跟大家熟知的自動化測試框架selenium webdriver類似,只是操作的目標不同而已。
運行環境
- Nodejs版本需要大于8.0
- 小程序基礎庫的版本需要大于等于2.7.3,需要注意的此處不是小程序最低支持的基礎庫的版本,而是本地調試基礎庫的版本
- 開發工具版本 : 1.02.1907232 及以上
SDK安裝
npm i miniprogram-automator --save-dev
?框架支持編寫語言
目前此框架僅支持通過JAVAscript來書寫自動化測試用例。
簡單應用
代碼片段
const automator = require('miniprogram-automator') const miniProgram = automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/macOS/cli', projectPath: '/Users/user/Desktop/miniprogram-quickstart-master/miniprogram-quickstart-master', }).then(async miniProgram => { const page = await miniProgram.reLaunch('/pages/index/index') await page.waitFor(500) const element = await page.$('.user-motto') console.log(await element.text()) await miniProgram.close() })
運行用例
將上述代碼保存到test.js中,然后運行命令如下:
node test.js
代碼講解
const automator = require('miniprogram-automator')
首先需要引入miniprogram-automator自動化包,此處需要注意的是代碼文件和miniprogram-automator包的地址的路徑問題,否則會出現類似Cannot find module 'miniprogram-automator' 這樣的問題出現。
const miniProgram = automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli', projectPath: '/Users/user/Desktop/miniprogram-quickstart-master/miniprogram-quickstart-master', }).then(async miniProgram => { })
此塊創建了miniProgram的實例,該模塊提供了控制小程序的方法automator.launch用來啟動并連接微信開發者工具。
cliPath: 工具cli位置,默認路徑是/Applications/wechatdevtools.app/Contents/MacOS/cli
projectPath: 項目文件路徑
此處是通過cli命令行來啟動微信開發者工具,要達到此目的,需要注意以下前提條件:
1、確保工具安全設置中已開啟 CLI/HTTP 調用功能。
開發者工具菜單中的設置->安全設置->服務端口
2、開啟小程序自動化功能
cli --auto <project_root> --auto-port <port> const page = await miniProgram.reLaunch('/pages/index/index')
此處是通過調用miniProgram提供的relaunch方法創建了一個page的實例,page模塊提供了控制小程序頁面的方法,relanch方法會關閉所有的頁面,打開到應用內指定的頁面。里面中的參數是頁面的路徑,此路徑可以從app.json文件中獲取到。
await page.waitFor(500)
此處是調用page的waitFor方法,等待直到指定條件成立,方法的參數是number類型,該參數會被當成超時時長,當經過指定時間后,結束等待。這塊屬于隱式等待,如果想進行顯示等待的話,可以傳入string或是function類型。
const element = await page.$('.user-motto')
此處是調用page模塊的$方法,用來獲取頁面元素,參數是元素的選擇器字符串,定位element元素時可以在微信開發者工具調試器中wxml處進行調試。
await miniProgram.close()
此處調用miniProgram模塊的close方法關閉與小程序運行的連接并且關閉項目窗口。
Miniprogram-automator + Jest模式
Miniprogram-automator 這個僅僅是小程序自動化的sdk,說直白些,僅提供了一些API,并不是真正意義上的測試框架,這意味著上述的代碼僅僅是JavaScript的代碼片段,而非真正意義上的自動化測試用例,要達到真正書寫自動化測試用例,需要一款測試框架,該框架可以是市面上任意一款node.js的javascript框架。miniprogram-automator負責操作小程序頁面的信息,測試框架負責組織和斷言。
測試框架選取與安裝
此處使用時下比較流行的facebook出品的一款測試框架Jest,該框架集成了眾多框架的功能。
npm i jest -g
簡單應用
代碼片段
const automator = require('miniprogram-automator') describe('小程序自動化測試初體驗', () => { let miniProgram beforeAll(async () => { miniProgram = await automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli', projectPath: '/Users/user/Desktop/miniprogram-quickstart-master/miniprogram-quickstart-master', }) }, 30000) it('測試微信用戶座右銘是hello world', async () => { const page = await miniProgram.reLaunch('/pages/index/index') const user_motto = await page.$('.user-motto') expect(await user_motto.text()).toBe('Hello World') }) afterAll(async () => { await miniProgram.close() }) })
運行用例
將上述代碼保存到quickstart.test.js中,然后運行命令如下:
jest quickstart.test.js
測試結果如下
代碼講解
此處僅講解與純miniprogram-automator模式不一樣的代碼部分。
describe('小程序自動化測試初體驗', () => { let miniProgram beforeAll(async () => { miniProgram = await automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli', projectPath: '/Users/user/Desktop/miniprogram-quickstart-master/miniprogram-quickstart-master', }) }, 30000)
因為Jest集成了Mocha,chai,jsdom,sinon等功能,所以這些框架的語法都可以在Jest應用,describe此處就是起test suite的意義。
beforeAll屬于測試生命周期API的一種,用在所有測試用例開始前執行。此方法可以進行一些測試初始化的操作。
30000 屬于設置的Jest的超時時間,因為工具項目窗口啟動初次編譯需要一定時長,Jest 默認 5 秒超時太短,所以需要修改如此。
it('測試微信用戶座右銘是hello world', async () => { const page = await miniProgram.reLaunch('/pages/index/index') const user_motto = await page.$('.user-motto') expect(await user_motto.text()).toBe('Hello World') ? })
此處屬于具體的測試用例,可以用it,也可以用test關鍵字。
toBe是matcher函數,使用expect和”matcher”函數結合驗證屬于具體的斷言部分。判斷實際得到的結果跟預期結果是否一致。
afterAll(async () => { await miniProgram.close() })
afterAll也屬于測試生命周期API的一種,用來在所有用例執行完畢后執行,此處可以進行一些清理收尾工作。
注:本文是針對小程序快速啟動模板項目https://github.com/wechat-miniprogram/miniprogram-quickstart 做的自動化測試。