方格精選

用 Spectron 對 Electron App 做測試

閱讀時間約 10 分鐘
圖片來自 Thor Alvis

Electron

Electron 是 Node.js 生態圈的框架,用於開發跨平台桌面應用,目標平台可以是 Mac / Linux / Windows,可以視為把 web app 包裝成執行檔在自己的視窗內運行,並且透過 Electron 框架讓這支 app 有與作業系統層溝通的能力,包括存取檔案、週邊裝置等,很多目前原生 web API 無法實現的能力都可以透過 Electron 辦到。
最知名的 Electron 應用應該就是 VSCode 了,這款當代最棒的編輯器也是運用了 Electron 框架達成在桌面端跨平台的能力。

Electron 的測試

對最大宗的 Windows 平台的 Windows Forms 這類的原生桌面應用來說,市場上已經有許多 RPA 工具可以用於自動化測試,但因為 Electron 在介面元件上並未調用系統原生元件,而是由 HTML 元素來構成介面,而那些 RPA 工具都無法抓取到 HTML 元件,導致 RPA 完全無用武之地。
既然沒有 GUI 測試工具可以用,只能回歸寫 code 測 code 這招,Electron 有自己的測試框架 Spectron,Spectron 也可以搭配 Mocha 等其它 JavaScript 測試框架使用,網路上爬文一下可以發現大部分也都就是 Spectron 配 Mocha 這樣的組合。

Mocha & Matcha來源:劍橋詞典

Spectron + Mocha

Electron App

像做菜節目一樣,前面都要先備料,我們必須先有一支 Electron app 來當作我們的測試 app,這裡我們用 Mini Diary 這個 app 當作待測的目標,因為它夠簡單又夠複雜,所謂夠簡單-它的 app 本身功能簡單,操作也簡單;所謂夠複雜-它是 Electron 加 React 的架構,又搭配了一些 React 生態圈的套件;另一個夠複雜-它除了提供原始碼外,也幫我們打包好了各個平台上的安裝檔。
在這裡我們用 Mini Diary 的 macOS 套件包來使用,依照通用的流程安裝,它會被安裝到 /Applications/ 目錄內,主程式就是 「/Applications/Mini Diary.app/Contents/MacOS/Mini Diary」 這支檔案。

版次搭配

前面提過 Electron app 是由 HTML 構成,為了在桌面前端 render 出這些 HTML,Electron app 裡面有包了一個 Chromium 做為前端的 renderer。而 Electron 的測試框架-Spectron,裡面也有一個 ChromeDriver 做為與 Electron 溝通的介面,就像純 web 常用的自動化測試工具 Selenium 也是透過 ChromeDriver 來操控 Chrome 一樣。
因為有 Chromium 與 ChromeDriver,就會有版次搭配的問題,兩者必須是相匹配的版次才可以成功的運作。
在 Electron 方面,electron-releases 這個專案內有列出各版本的 Electron 與 Chromium 的對應關係,以 Mini Diary 來說,它的 Electron 是 8.3.0 版,透過 Electron / Chromium 版次表,可以查到對應的 Chromium 版次是 80。
在 Spectron 方面,它的專案文件同時也列出了 Spectron 與 Electron 的對應表,透過查表可以知道 Electron 8.x 須與 Spectron 10.x 相互搭配。

專案建置

這裡我們為測試另建一個專案,叫做 minidiary-test,建立同名資料夾後,git init 和 npm init 一下,接著把 Mocha 和 Spectron 裝起來:
npm install mocha spectron
記得前面說的版次搭配性問題,有必要的話需指定 spectron 的版次。

測試程式

const Application = require("spectron").Application
const assert = require("assert");

describe("My Test App", function () {
// SETUP section
let app;
this.timeout(20000)
before(function () {
app = new Application({
path: `/Applications/Mini Diary.app/Contents/MacOS/Mini Diary`,
});
return app.start()
.catch(console.error)
});
// shutdown after all tests
after(function () {
if (app && app.isRunning()) {
return app.stop();
}
});
// TESTS section
// test 1
it("Should have the correct title", async function () {
const title = await app.client.getTitle();

assert.equal(title, "Mini Diary");
});
});
能測試 Electron 的關鍵就在上面程式碼內的 app,把 app 定義出來後,就可以利用 Spectron 的 API 去存取 Electron app 的各項屬性,再配合 Mocha 的測試架構即可讓我們做到 Electron app 測試自動化。除了 app 以外的部分,describe()、it() 等都是 Mocha 的測試用函示,關於 Mocha 的用法請自行參閱 Mocha 的網站或其他大大們的文章。
跑看看測試:
npx mocha test/test.js
結果正常的話應該像這樣:
My Test App
✓ Should have the correct title
1 passing (4s)
在上面的範例程式碼中,只有很簡單的確認 app 的標題是否為 Mini Diary,在實際的測試場景中顯然會更複雜,應該會有大量的調用 Sepctron API 對 app 進行自動化操作以及確認 app 視窗內的屬性值是否與預期相符,以及需要用 Chrome 開發者工具來查找元素與操作 console 等,這部分只能先富奸了

Spectron & WebdriverIO

WebdriverIO 是一個 JavaScript 的測試套件,它提供了一層 API 讓我們可以調用瀏覽器與網頁,雖然前面都沒提到它,但其實它也算是 Spectron 的一部分,在安裝 Spectron 的時候 WebdriverIO 也會被裝進專案內。Spectron 就是利用了 WebdriverIO 的 API 來提供給我們操控 Chromium 與 Electron app 頁面的能力,可以更具體地說,Spectron 只是對 WebdriverIO API 做了一層封裝,在 WebdriverIO API 文件內能調用的函式也都可以在 Spectron 上面做調用。
附帶提醒,延續前面提到的版次問題,新舊版的 Spectron 依賴的 WebdriverIO 也會有新舊版的問題,確認一下專案 package.json 內 webdriverio 套件的版次,並且查閱 API 文件時也要注意文件版次與專案內安裝的 webdriverio 版次要相符。
回歸正題,想要在測試腳本裡面去操控頁面元素的話,就必須利用 Spectron 的 API(也就是被封裝過的 WebdriverIO API)。
首先是選擇器,先上範例:
let accountField = app.client.$('.account-input');
accountField.setValu('user1');
看到熟悉的 $() 錢字號函數與後面的 CSS 選擇器語法,和 jQuery 長一樣,雖然長一樣,不過 WebdriverIO 並不依賴 jQuery,只是借鑒錢字號這樣的函數命名而已,大概是希望提高對開發者的親切感吧。
在上面的範例的第二行,把元素抓到之後,就可以操作它,除了範例內做的填值之外,取值、點擊等都可以被實現。詳細的可調用的函式,請參考 WebdriverIO 文件。

參考資料

其它測試工具

  • TestComplete:Windows 桌面端收費商業應用,可以拿來測 Electron,好像很厲害,也很貴的貴。
  • Squish:跨平台自動化測試工具,也是很貴的貴。
為什麼會看到廣告
13會員
64Content count
Where I go and what I get.
留言0
查看全部
發表第一個留言支持創作者!
Leon的沙龍 的其他內容
古早的年代想在網頁內埋 Java 還有 Java applet 可以用,在 Java applet 式微後,找來找去比較可以的辦法大概就是編譯成 WebAssembly 了吧! 想要把 Java 編譯成 WebAssembly,有下面三個工具可以選用
古早的年代想在網頁內埋 Java 還有 Java applet 可以用,在 Java applet 式微後,找來找去比較可以的辦法大概就是編譯成 WebAssembly 了吧! 想要把 Java 編譯成 WebAssembly,有下面三個工具可以選用
你可能也想看
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
一隻手能做出雪球嗎? 不能,要用兩隻手才行。同樣的,一個巴掌也拍不響。和平需要兩方合作,仇恨也是兩方共同建立的。 -追蹤、訂閱《郝廣才日日談》來閱讀全文,每周二、四為你說故事。
Thumbnail
HackMD是由Markdown 台灣社團發起人吳承翰開發的線上多人協作共筆平台,使用Markdown語法作為編輯文件的工具,可以輕易的編輯出美觀易讀的文件,適合用來傳播知識或是做為筆記平台。
Thumbnail
在使用Garment Maker做衣服前有兩個前置作業要注意 1.所有區段不能重疊 2.這樣做是避免程式錯誤 3.所有區段必須中斷連結 這也是避免在Create Seams時發生錯誤 所以要再使用Garment Maker前,選取線段的vertex模式,選取所有點,並點選Geometry
Thumbnail
1.首先填滿顏色  2.然後再點選濾鏡→紋理→紋理化  英文:Filter→Texture→Texturixer  3.按確定 4.濾鏡→風格化→擴散  英文:Filter→Stylize→Diffuse 
陳健民說,為了準備入獄,他停用冷氣達兩年之久。我不算很怕熱,在一、兩年前,也已停用冷氣,雖然主因是受不了老舊嘈吵的機件聲。岳義士說,獄中最難捱的正是伙食,「南乳花生汁配炸池魚」尤其令他心驚膽顫,「好腥啦,啲汁紫色㗎啦,只會淨係食菜同飯嘅啫,唔會食個汁嘅」。自問不算是嗜吃的食家,但身為對食有種執着的香
Thumbnail
少有人會對一支比賽品質差,戰績爛,又沒「大牌明星球員」的球隊感到興趣。
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
一隻手能做出雪球嗎? 不能,要用兩隻手才行。同樣的,一個巴掌也拍不響。和平需要兩方合作,仇恨也是兩方共同建立的。 -追蹤、訂閱《郝廣才日日談》來閱讀全文,每周二、四為你說故事。
Thumbnail
HackMD是由Markdown 台灣社團發起人吳承翰開發的線上多人協作共筆平台,使用Markdown語法作為編輯文件的工具,可以輕易的編輯出美觀易讀的文件,適合用來傳播知識或是做為筆記平台。
Thumbnail
在使用Garment Maker做衣服前有兩個前置作業要注意 1.所有區段不能重疊 2.這樣做是避免程式錯誤 3.所有區段必須中斷連結 這也是避免在Create Seams時發生錯誤 所以要再使用Garment Maker前,選取線段的vertex模式,選取所有點,並點選Geometry
Thumbnail
1.首先填滿顏色  2.然後再點選濾鏡→紋理→紋理化  英文:Filter→Texture→Texturixer  3.按確定 4.濾鏡→風格化→擴散  英文:Filter→Stylize→Diffuse 
陳健民說,為了準備入獄,他停用冷氣達兩年之久。我不算很怕熱,在一、兩年前,也已停用冷氣,雖然主因是受不了老舊嘈吵的機件聲。岳義士說,獄中最難捱的正是伙食,「南乳花生汁配炸池魚」尤其令他心驚膽顫,「好腥啦,啲汁紫色㗎啦,只會淨係食菜同飯嘅啫,唔會食個汁嘅」。自問不算是嗜吃的食家,但身為對食有種執着的香
Thumbnail
少有人會對一支比賽品質差,戰績爛,又沒「大牌明星球員」的球隊感到興趣。