如何使用Node爬蟲利器Puppteer進行自動化測試

文:華為雲DevCloud 樂少

1、背景

1.1 前端自動化測試較少

前端瀏覽器眾多導致頁面兼容性問題比較多,另外界面變化比較快,一個月內可能頁面改版兩三次,這樣導致對前端自動化測試較少,大家也不是很care。18年英國的一位開發者做過一些前端測試工具調查如圖1-1所示。從圖中可以發現有43%的用戶未使用過任何前端測試工具。

如何使用Node爬蟲利器Puppteer進行自動化測試

圖1-1

1.2 基於Puppteer的自動化測試

Puppeteer(中文翻譯為“木偶”)是Google Chrome團隊官方的無界面(Headless)Chrome工具。這是一個node庫。提供高級API來控制DevTools協議無頭版Chrome。Chrome的DevTools提供了非常之多和非常方便的頁面工具,而Puppteteer則把這種能力通過Headless方式提供出來,可以在Linux操作能力,必將成為web應用的自動化測試行業標杆,場景非常之多。

1.3 解決實際問題

筆者是在華為雲DevCloud的前端團隊,團隊採用前端微服務架構,也就是說,有很多前端portal,同時每個portal有若干個前端開發進行開發維護,開發之間溝通交流較少,而且還是在異地進行開發。但每個服務同屬於DevCloud產品,所以頁面體驗、場景、控件、術語都需要保持一致,如果通過人工的方式來對每個服務頁面進行檢測是十分困難的一件工作。

2、Puppeteer能做什麼

可以這麼說,在chrome瀏覽器手動能完成的大部分事情可以使用puppteteer完成!你可以操作頁面的dom、抓取內容等等。另外puppeteer還可以:

  • 生成頁面的截圖和PDF;
  • 抓取SPA並生成預先呈現的內容(SSR)
  • 從網站上抓取你所想要的內容。自動錶單提交,UI測試,鍵盤輸入等等
  • 創建一個最新的自動化測試環境,使用最新的JavaScript和瀏覽器功能,直接在最新版的chrome中運行測試。

3、Puppeteer版本

我最早使用的版本是[email protected]版本,通過npm i pupptetter下載。裡面包含自帶瀏覽器版本。如圖所示3-1所示。

如何使用Node爬蟲利器Puppteer進行自動化測試

圖3-1 puppeteer自帶瀏覽器

在版本1.7.0之後,google把puppeteer拆成puppteteer-core和瀏覽器兩部分。也就是說瀏覽器需要自己手動去下載。下載地址可以通過華為雲鏡像站(http://t.cn/EJiCszB)搜索chromium進行匹配下載,如圖3-2所示。

如何使用Node爬蟲利器Puppteer進行自動化測試

圖3-2 puppteteer瀏覽器chrome下載

當然不同的puppeteer-core版本匹配不同的瀏覽器版本,不然會有報錯。版本匹配如圖2-3所示。大家也可以在官網github上進行查看:
https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md

如何使用Node爬蟲利器Puppteer進行自動化測試

圖3-3 puppeteer版本匹配

4、 輕鬆入門

這部分包括windows和linux上的配置和運行。因為最終是需要部署到linux服務上去。

4.1 簡單實現

如果windows下使用puppeteer非常容易,在package.json加上下面一行代碼:

"puppeteer-core": "1.13.0",

下面是一點簡單截頻實現:

const puppeteer = require('puppeteer');
(async () => {
 const browser = await puppeteer.launch();
 const page = await browser.newPage();
 await page.goto('https://example.com');
 await page.screenshot({path: 'example.png'});
 await browser.close();
})();

4.2 基本語法

這些是puppeteer一些基礎的語法,可以滿足一些常用功能。

async/await

看官方的例子就可以看出來,幾乎所有的操作都是異步的,如果堅持使用回調或者Promise.then 寫出來的代碼會非常醜陋且難讀,Puppeteer 官方推薦的也是使用高版本 Node 用 async/await 語法

async確保了函數返回一個promise,即使其中包含非promise。夠簡單了吧?但是不僅僅只是如此,還有另一個關鍵詞await,只能在async函數里使用,同樣,它也很cool。

關鍵詞await可以讓JavaScript進行等待,直到一個promise執行並返回它的結果,JavaScript才會繼續往下執行。

let value = await promise

查找元素

這是 UI 自動化測試最常用的功能了,Puppeteer 的處理也相當簡單

page.$(selector)

page.$(selector)

這個在底層依然是執行document.querySelector和document.querySelectorAll。但返回的不是dom對象。而是封裝的。

獲取DOM屬性

我們寫爬蟲爬取頁面圖片列表,感覺可以通過 page.$$(selector) 獲取到頁面的元素列表,然後再去轉成 DOM 對象,獲取 src,然後並不行,想做對獲取元素對應 DOM 屬性的獲取,需要用專門的 API:page.$eval(selector, pageFunction[, ...args])

Evaluate

如果我們有一些及其個性的需求,無法通過 page.$() 或者 page.$eval() 實現,可以用大招——evaluate。如下所示:

const result = await page.evaluate(() => {
 return Promise.resolve(8 * 7);
});
console.log(result); // prints "56"
const aWindowHandle = await page.evaluateHandle(() => Promise.resolve(window));
aWindowHandle; // Handle for the window object. 相當於把返回對象做了一層包裹
 

性能

通過 page.getMetrics() 可以得到一些頁面性能數據。

  • Timestamp The timestamp when the metrics sample was taken.
  • Documents 頁面文檔數
  • Frames 頁面 frame 數
  • JSEventListeners 頁面內事件監聽器數
  • Nodes 頁面 DOM 節點數
  • LayoutCount 頁面 layout 數
  • RecalcStyleCount 樣式重算數
  • LayoutDuration 頁面 layout 時間
  • RecalcStyleDuration 樣式重算時長
  • ScriptDuration>
  • TaskDuration 所有瀏覽器任務時長
  • JSHeapUsedSize JavaScript 佔用堆大小
  • JSHeapTotalSize JavaScript 堆總量

會返回如下數據:

{ 
 Timestamp: 382305.912236,
 Documents: 5,
 Frames: 3,
 JSEventListeners: 129,
 Nodes: 8810,
 LayoutCount: 38,
 RecalcStyleCount: 56,
 LayoutDuration: 0.596341000346001,
 RecalcStyleDuration: 0.180430999898817,
 ScriptDuration: 1.24401400075294,
 TaskDuration: 2.21657899935963,
 JSHeapUsedSize: 15430816,
 JSHeapTotalSize: 23449600 
}

更多功能請查看puppeteer的github官網。

https://github.com/GoogleChrome/puppeteer#usage

4.3 Linux安裝Puppeteer

windows下調試好的項目,在linux上運行,還是需要費一番功夫,需要配置更多的參數。如下:

一、下載相關依賴包,這些依賴包都是chrome運行所需要的。

yum install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 \
libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 \
alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi \
xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc

二、字體安裝:

yum install ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc

三、增加—no-sandbox –disable-setuid-sandbox

const browser = await puppeteer.launch({args:['--no-sandbox', '--disable-setuid-sandbox']})

筆者的工作環境比較複雜,中間因為權限問題導致運行報錯,這個時候需要增加一些代理設置。

5、puppeteer體驗度量實踐

前面主要是講一些puppeteer基本功能和實踐。那我們基於puppeteer怎麼解決實際問題的呢。

5.1 規範的建立

在使用puppeteer之前,需要先梳理各微服務使用的場景,以及術語規範等,梳理清楚之後在來進行工具自動化。首先我們參照尼爾森可用性原則。

如何使用Node爬蟲利器Puppteer進行自動化測試

上面這位略顯陰柔的帥哥就是尼爾森(Jakob Nielsen),人機交互學博士。他通過自己的郵件列表以及網站,向成千上萬的web設計師傳授web易用性方面的只是。是web設計師眼中的頂尖領袖。Jakob Nielsen在1995年發表了“尼爾森十大可用性原則”。

在尼爾森十大原則裡有一項是UI一致性原則,我們基於這個梳理出DevCloud的一些細化的點,並給出每個測試因子的權重和分值,計算出各個服務的UI體驗,最後換算成百分值,最後加權計算服務體驗總分。圖5-1就是我們梳理出來的部分規則。

如何使用Node爬蟲利器Puppteer進行自動化測試

圖5-1 測試分類

5.2 具體使用puppteer

在上面建立規則之後,我們再針對每個檢測項評估是否可以量化,怎麼量化。比如我們想檢測組件的覆蓋度。圖4-2是我們產品所使用的公共組件庫。都是以ave-開頭,checkbox的命名就是ave-button。那普通的checkbox則是以input[type=checkbox]來寫的。我們針對每個服務去掃面線上各個頁面,看使用ave-check和使用原生input checkbox的數量,這樣就能統計出組件庫的覆蓋度。最終驅動各服務去整改。

通過組件的形式使得各個服務體驗基本一致。

如何使用Node爬蟲利器Puppteer進行自動化測試

圖5-2 DevCloud組件庫

最終通過圖表的形式來進行展示。如圖5-3所示。

如何使用Node爬蟲利器Puppteer進行自動化測試

圖5-3 ave-checkbox覆蓋度

從圖上我們可以看到ave-checkbox得到整改。

通過以上的方式,我們可以在組件、樣式、以及體驗旅程方面都能很好的把握整個產品設計是否與我們預期是一致的。

我們團隊在自動化方面一直在探索,除了在前端測試、接口測試以及編譯構建方面也一直遵從能夠使用工具提升效率,絕不靠人工來進行檢測的理念,不斷的實踐,極大的減少了人力成本。當然這些能力也一直是對外開放的:華為雲軟件開發服務DevCloud。也歡迎大家來建議和探討。

​​​​​​​6、 參考資料及擴展閱讀材料

The Front-End Tooling Survey 2018 - Results

尼爾森可用性十大原則

https://www.jianshu.com/p/53daaa5ba794

華為雲DevCloud作為一站式雲端DevOps平臺,集成華為近30年研發實踐和前沿理念,面向開發者提供研發工具服務,讓軟件開發簡單高效。現支持5人以下額度範圍內,可以免費使用,並且可以預約免費的產品演示和技術交流,詳情查看華為雲官網:http://t.cn/EJia5sX


分享到:


相關文章: