走進 phantomjs 嵌入式測試

發表於2015-10-01

Google 上搜尋了下 phantomjs  關鍵詞,展示最多的是測試和截圖相關的內容。phantomjs 提供了大量的 API,讓我們可以操作 webkit 網頁沙箱中的內容,也可以將網頁中的資訊輸出到外層,進行分析處理。而本文著重要講述的是,如何更好的與 webkit 網頁沙箱互動,如何注入指令碼,如何修改請求。

QA 測試最煩惱的是 UI 測試,包括網頁元素的正確呈現,網頁互動之後的元素變化等,人工測試很容易疏忽一些問題,並且 UI 層面的測試用例也不好寫,這讓人很頭痛。為了讓程式能夠很好地分析頁面 UI,也有很多人做了圖片對比工具,通過 phantomjs 提供的 screen capture 功能,定時抓取頁面截圖,或者在不同的場景下抓取同一個頁面的截圖,在時間維度和空間維度上對頁面圖片做對比分析,做監控警報等。技術成本不是很高,但是為了個性需求需要做很多額外的工作。

為了能夠在精確的時間點注入測試指令碼,我們需要了解下 phantomjs 在請求資源時會發生哪些事件,畢竟它也是一個事件驅動模型。

  • onInitialized 類似於我們傳送 ajax 請求,狀態為 0 的時候
  • onLoadStarted 準備載入網頁,此時頁面的  page.content  是存在的,內容為  <html><body></body></html>
  • onLoadFinished 頁面載入完成,是  DOMContentLoaded 還是  window.onload ,我稍微測試了下,感覺應該是後者
  • onResourceRequested 請求資源,如 css、js 等
  • onResourceReceived 請求的資源已到達
  • onClosing 關閉頁面
  • onConsoleMessage 沙箱內的 console 內容是不會出現到外層的,通過這個函式可以輸出

還有很多,具體可以翻閱文件: http://phantomjs.org/api/webpage/。這些事件都是開啟一個頁面之後的例項化物件上的:

用慣了 nodejs 的同學,可能會很自然的在程式碼裡頭寫

我們需要搞清楚的是 phantomjs 是一個基於 webkit 核心的 JS API,webkit 包含兩方面,一個是 webCore 解析 html,一個是 V8 解析和執行 javascipt,phantomjs 包含了 webkit 和基於 webkit 的 js 封裝,相比單純的 webkit 它提供了更多的 API。而 nodejs 是對 v8 的封裝,在 v8 上做了一些上層建築。要搞清楚 phantomjs 和 nodejs 之間的界限。

實際上,phantomjs 自己也做了一些類似 nodejs 的 API 包裝,比如 webserver、child_process、FileSystem 等等,這些 API 可以讓我們很方便的操作網路 IO 和系統程式。

嵌入式指的是,將測試程式碼嵌入到 phantomjs 的沙箱之中,然後通過它提供的 API 將測試資料匯出來,那麼,如何將資料插入進去?

1. includeJS/injectJS注入檔案

兩個函式都可以網沙箱內注入程式碼,區別是  includeJS 主要用於注入一個遠端的指令碼,如:

2. evaluate注入程式碼

而  injectJS 主要用於注入本地的檔案,在做測試的時候,這個函式的使用頻率稍高一些。很多的測試平臺都是線上的,並且支援線上編寫測試用例,最後生成的指令碼地址當然也是網路可訪問的,那麼這個時候用  includeJS 就略微方便一些啦。

上面兩種方式是想容器內注入可執行穩緊啊。除此之外,我們還可以使用  evaluate 直接注入可執行的指令碼內容,如:

這種方式有點類似於我們在 chrome devtoos 的控制檯中輸入程式碼進行測試。

注入程式碼拿到輸出之後,我們需要將資料拿出來,在執行的環境中,可以通過如下手段將資料搬出來。

1. 多開幾個 webserver

上面提到,phantomjs 提供了 webserver 方面的 API,我們可以在注入的程式碼中:

向外部通訊,而我們在外部也準備好了接駕程式碼:

所以 http 是個好東西,我們可以控制 web 的 server(沙箱外) 和 client(沙箱內),那麼資料通訊就不是問題了。

2. callPhantom 函式

phantomjs 的 webpage 物件提供了一個  onCallback 函式,這個函式能夠聽到沙箱內一個叫做  callPhantom 函式的吶喊。 callPhantom 是 phantomjs 在 window 上擴充套件的函式,他的使用:

所以一切都是那麼簡單!知道了這些之後,還有啥事我們辦不成的呢?!

Jasmine 和  QUnit 是兩套用的比較多的測試框架,我們可以使用上面任一種方式進行測試開發。

自動化測試少不了這些有用的工具,這些工具能夠讓我們在網頁初始化的任何階段注入測試程式碼,所以我們可以寫好一堆測試用例,作為持續整合的測試庫,讓上線的程式碼更安全、更乾淨!

相關文章