前端自動化測試探索
背景
測試是完善的研發體系中不可或缺的一環。前端同樣需要測試,你的css改動可能導致頁面錯位、js改動可能導致功能不正常。由于前端偏向GUI軟 件的特殊性,盡管測試領域工具層出不窮,在前端的自動化測試上面卻實施并不廣泛,很多人依舊以手工測試為主。本文試圖探討前端自動化測試領域的工具和實 踐。
為什么需要自動化測試
一個項目最終會經過快速迭代走向以維護為主的狀態,在合理的時機以合理的方式引入自動化測試能有效減少人工維護成本。自動化測試的收益可以簡單總結為:
自動化的收益 = 迭代次數 * 全手動執行成本 - 首次自動化成本 - 維護次數 * 維護成本
對于自動化測試來說,相對于發現未知的問題, 更傾向于避免可能的問題 。
可測試方向
首先本文 不會探討單元測試方向 ,因為單測已經有完善的工具體系。但前端開發中,除了一些框架和庫,愿意去寫單測的少之又少。另外單測維護成本較高,而且也沒法滿足前端測試的所有需求。
前端自動化測試可以在幾個方向進行嘗試:
-
界面回歸測試測試界面是否正常,這是前端測試最基礎的環節
-
功能測試測試功能操作是否正常,由于涉及交互,這部分測試比界面測試會更復雜
-
性能測試頁面性能越來越受到關注,并且性能需要在開發過程中持續關注,否則很容易隨著業務迭代而下降。
-
頁面特征檢測有些動態區域無法通過界面對比進行測試、也沒有功能上的異常,但可能不符合需求。例如性能測試中移動端大圖素材檢測就是一種特征檢測,另外常見的還有頁面區塊靜態資源是否符合預期等等。
業界開源工具
工欲善其事,必先利其器。業界在自動化測試領域已經有不少優秀的框架和庫,善于利用能事半功倍。
界面回歸測試
界面回歸測試常見的做法有 像素對比 和 dom結構對比 兩個方向。
像素對比
像素對比基本的思想認為,如果網站沒有因為你的改動而界面錯亂,那么在截圖上測試頁面應當跟正常頁面保持一致。可以跟線上正常頁面對比或者頁面歷史記錄對比。像素對比能直觀的顯示圖像上的差異,如果達到一定閾值則頁面可能不正常。
PhantomCSS
像素對比比較出名的工具是 PhantomCSS 。 PhantomCSS結合了 Casperjs 截圖和 ResembleJs 圖像對比分析。單純從易用性和對比效果來說還是不錯的。
不支持PhantomJS 2.0的問題
由于PhantomJS 2.0暫時禁用了文件上傳,PhantomCSS默認不支持PhantomJS 2.0 。如果還是想使用可以修改源碼中獲取圖片文件的方式,改為通過ajax獲取同域名下文件的方式,具體可以參考ResembleJs官網示例。
如何測試多瀏覽器
如果想測試多瀏覽器下的兼容性情況,只需要拿到多個瀏覽器下的截圖即可。多瀏覽器測試最出名的當屬 selenium , selenium可以自動化的獲取多個瀏覽器下的截圖,前端工程師來說還可以借助Node的 webdriver 來輕松開發測試腳本。
但selenium的安裝和上手成本要稍大些,而且對于多瀏覽器來說,各個瀏覽器之間的兼容性對比容易出錯。不同瀏覽器截圖可能一像素的偏差就導致截屏對比失敗,多瀏覽器可能 更適用回歸性測試 。
響應式頁面測試
國外有人將像素對比應用到了響應式頁面上,如果您針對PC和移動設備使用同一個網頁,響應式測試可以很快的回歸你的頁面在不同尺寸上的頁面是否正常。與單純針對移動端開發的響應式不同,同時支持PC移動的頁面更容易發生錯亂。
例如 BackstopJS 項目,便是通過PhantomJS、capserJS等工具在不同尺寸下截圖然后根據resemberJS進行像素比對判斷是否正常:
像素對比需要注意的問題
-
不建議對網站所有頁面進行測試 這只會導致很容易出現告警,但不一定是錯誤。針對重復使用的組件和樣式、容易出問題的區域測試更加有效
-
推薦測試區域而不是整個頁面 整個頁面的測試導致任何一點文字、圖像等動態的改變都可能導致不通過,而且真正的錯誤可能由于圖像太大而被閾值忽略。圖像越大對比也越容易超時。
-
隱藏動態區域 在選擇器對應的區域如果有動態元素,可以同樣通過選擇器來隱藏
-
界面對比只是一個環節,需與其他測試相結合 沒有銀彈,合理結合才是關鍵
dom結構對比
像素對比雖然直觀,但動態元素居多且無法保證測試頁面與線上頁面同步時有所局限。 @云龍 大牛針對這個問題提供了新的解決方案 page-monitor ,根據dom結構與樣式的對比來對比整個頁面的變動部分。 使用效果示例:
通過page-monitor你可以很快的搭建一個監控系統,監控頁面的文字、樣式等變動情況。
像素對比和dom結構對比各有優勢,但也無法解決全部問題。何不綜合利用呢?FEX部門QA同事就結合了兩種方式提供了pagediff平臺,正在對外公測中!有興趣可以體驗一把吧~ http://pagediff.baidu.com
QA同學開發的平臺都這么炫,作為前端怎么能不了解一點測試知識呢?
用戶操作測試
上面提到界面回歸測試 無法取代功能測試 。即便是界面正常,功能正常也是必須關注的部分。最直接的功能測試就是模擬用戶操作,通過模擬正常的操作流程來判斷頁面展現是否符合預期。
Phantomjs、CasperJS
大名鼎鼎的PhantomJS當然要隆重介紹啦!前面界面對比測試基本都是基于PhantomJS開發的, Phantom JS是一個服務器端的 JavaScript API 的 WebKit。其支持各種Web標準: DOM 處理, CSS 選擇器, JSON, Canvas, 和 SVG。對于web測試、界面、網絡捕獲、頁面自動化訪問等等方面可以說是信手拈來。
casperjs是對PhantomJS的封裝,提供了更加易用的API, 增強了測試等方面的支持。例如通過CasperJS可以輕松實現貼吧的自動發帖功能:
casper.test.begin('測試發帖功能', function suite(test) { //登錄百度 casper.loginBaidu();//實現略,可以通過cookie或者表單登錄實現 casper.thenOpen('http://tieba.baidu.com/p/3817915520', function () { var text = "樓主好人"; //等待發帖框出現 this.waitForSelector( '#ueditor_replace', function() { //開始發帖 this.echo("開始發帖。發帖內容: " + text,"INFO"); //執行js this.page.evaluate(function(text) { $("#ueditor_replace").text(text); $("a.poster_submit").click();//點擊提交 },text); },function(){ test.fail("找不到發帖框#ueditor_replace"); } ); }) .run(function () { test.done(); }); });
通過前端最熟悉的語言,短短幾十行代碼便可輕松失效自動發帖的功能,還可以在其中添加一些測試邏輯來完善case。
相對于單測來說,casperjs能用簡單的API、從真實用戶操作的角度來快速測試網站的功能是否正常,并且可以保留每一步測試的截圖最終實現操作流可視化。例如下面這個 GitHub項目 便使用Casperjs測試一個電子商務網站的登錄、下單等重要流程是否正常。case完善之后一條命令便可測試整個網站。
casperjs能監聽測試和頁面的各個狀態進行截圖等操作,如果針對測試運行結果稍作優化,便可以形成一個可視化操作流:
通過這個能直觀的看到各個操作的情況以及錯誤的步驟(如有錯誤圖片將飄紅),下面則可以看到casper 測試的詳細日志輸出。
不想維護case?
除非有足夠的QA同學來幫你完成測試工作,否則通過人工來回歸肯定會消耗更多的精力。在項目功能基本穩定期,維護case會簡單的多,而且同樣建議針對網站核心功能而不是所有功能來添加case。
瀏覽器兼容測試
當然selenium同樣支持操作測試,類似的工具還有 dalekjs 等,如果想專門針對IE測試,可以考慮[triflejs] http://triflejs.org/,它提供了與PhantomJS基本類似的API。
PhantomFlow操作對比測試
有沒有像圖像對比一樣直觀,又能比較簡單的寫case的工具呢?可以考慮 PhantomFlow , PhantomFlow假定如果頁面正常,那么在相同的操作下,測試頁面與正常頁面的展現應該是一樣的。 基于這點,用戶只需要定義一系列操作流程和決策分支,然后利用PhantomCSS進行截圖和圖像對比。最后在一個很贊的可視化報表中展現出來。可以看下作者所在公司進行的測試可視化圖表:
圖片中代表不同的操作,每個操作有決策分支,每個綠色的點代表圖像對比正常,如果是紅色則代表異常。點擊進去可以查看操作的詳情:
不得不說這是一個不錯的構思,它將操作測試的case濃縮成決策樹,用戶只需要定義進行何種操作并對關鍵部分進行截圖即可。如果網站偏向靜態或者能保證沙盒地址數據一致性,那么用這個測試工具能有效提高實施自動化測試的效率。
性能測試
網站展現性能也越來越成為人們關注的點,尤其是移動端性能始終是一個影響體驗的重要因素。一般開發者都會利用自動化工具對資源進行合并壓縮等優化,很多大公司也都搭建自己的性能監控系統指導優化工作。性能監控可以參考我的另一篇文章 七天打造前端性能監控系統 。
需要注意的是性能并不是一個目標,而是開發、測試過程中需要持續關注的問題。我們有自動化的工具和框架在開發時進行優化,同樣可以借助工具在測試時進行性能測試。
這里推薦一個通樣是基于PhantomJS的工具 Phantomas ,它能運行測試頁面獲取很多性能指標,加載時間、頁面請求數、資源大小、是否開啟緩存和Gzip、選擇器性能、dom結構等等諸多指標都能一次性得到,并且有相應的 grunt插件 。你也可以對檢測指標進行二次開發,例如移動端定義一個最大圖片大小的規則,在開發的時候如果使用了超過限制的大圖則進行告警。不過如果把加載過程中的時間點作為常規的測試監控,則最好模擬移動端網絡環境。
頁面特征檢測與實踐
前面講到性能測試中測試資源大小其實就屬于一種資源特征,諸如此類我們還可以開發一些通用的測試規則,以測試頁面是否正常。這種測試主要適用于在界面和操作上無法直接進行判斷的元素。例如頁面中廣告部署是否正常。
廣告部署檢測實踐
第三方部署廣告以及物料配置的時候容易出現問題,例如代碼腳本升級出錯、部署錯誤、物料尺寸格式不對、廣告容器未適配多種屏幕大小、廣告是否可 見、時效廣告是否展現等。已知的問題就有很多,如果出現問題時由廣告系統的人員挨個檢測是一個很耗費人力的過程。而這些特征都是跟實際運行環境相關的,大 部分都可以通過casperjs之類的工具來進行檢測。
另外與廣告相關的還有屏蔽檢測等,檢測頁面div廣告區塊(非iframe廣告)是否被攔截插件所攔截。由于攔截插件使用的基本相同的攔截規則, 而且對于div廣告采用的是選擇器屏蔽,檢測過程中只需要根據相關的檢測規則判斷選擇器是否存在頁面中即可。這在casperjs中一個api即可搞定:
if(casper.exist(selector)){ casper.captureSelector(filename,selector); }
這樣便能直接截圖被攔截的區域了。
與自動化測試的結合
回到剛才的需求,如何通過casperjs實現這些檢測需求呢。casperjs支持執行JS來獲取返回結果:
this.page.evaluate(function(text) { $("#ueditor_replace").text(text); $("a.poster_submit").click();//點擊提交 },text);
而且可以主動注入jquery或者zepto等框架,這樣你就可以以非常簡單的方式來操作分析dom元素了。例如根據html結構特征獲取部署類型、自動掃描廣告檢測容器寬度、獲取廣告的選擇器來進行截屏等。如果頁面有報錯可以通過casper的api進行監聽:
casper.on("page.error", function(msg, trace) { this.echo(msg,'WARNING'); //詳細錯誤信息 if(trace){ this.echo("Error: " + msg, "ERROR"); this.echo("file: " + trace[0].file, "WARNING"); this.echo("line: " + trace[0].line, "WARNING"); this.echo("function: " + trace[0]["function"], "WARNING"); } });
還能捕獲網絡請求分析死鏈或者廣告請求:
//記錄所有請求 casper.on('resource.requested', function(req,networkRequest) { //do something });
更加贊的是你還可以進入到跨域的iframe里面去進行操作!
casper.withFrame(id/name,function(){ //now you are inside iframe })
注意: iframe操作時推薦用name,id有時候會發生錯位。
檢測示例:
可以說有這么贊的工具你能輕松實現很多意想不到的需求!
配置化減小成本
在開發了檢測工具之后,當然要想辦法減小使用成本,如上面例子中,只需將廣告檢測的一些規則和檢測頁面進行配置化,用戶使用的時候只需要關注需要測試哪些頁面而已。工具會根據用戶提交配置自動運行并將結果返還給用戶。
與CI的結合
講到這里,上面這些步驟很像ci系統啦!如果能通過ci實現一系列的自動化部署測試等工作,使用上就更加順暢了。
談起ci肯定要介紹 jenkins ,穩定可靠,是很多大公司ci的首選。只是在前端的眼中它看起來會感覺。。丑了點和難用了點。。如果能像 travis-ci 那樣小清新和直觀易用該多好哈哈。
當然如果你要自己實現一套類似ci的流程也不復雜,因為對于上面提到的自動化測試來說只需要一個隊列系統處理批量提交的測試任務然后將運行結果反饋給用戶即可。當然前端測試可能對于自定義的報表輸出要求更高點。如果你想實現一套,使用 laravel 和 beanstalkd 能快速搭建一套完善的隊列系統,laravel已經提供很多內置支持。各個服務的運行結果輸出成html報表,就能實現一套輕量級且支持自定義展現的ci系統了。這方面有很多教程,可以自行搜索。
國外做的比較好的輕量級ci系統有:
良好的用戶體驗讓人使用的心情愉悅沒有障礙,如果想定制可以作為參考。
實踐經驗
前端自動化測試可以說還是一個在不斷探索的領域,實施過程中也難免遇到問題。有些需要注意的點可以作為經驗參考。
減小使用和維護成本
自動化測試為人詬病的地方無外乎使用效果和使用成本,使用效果可以對癥下藥選擇合適的工具,而使用成本則可以通過一系列措施來減小到合理程度:
-
與構建工具結合
grunt、FIS,將自動化測試與構建工具結合能更早的發現問題,也能減小使用和維護成本
-
與持續基礎結合
與CI系統的結合能更大范圍更有效的發揮自動化測試的作用
-
與工作流結合
與日常工作流結合同樣是為了減少使用成本,如將結果通過自定義的方式反饋給用戶等。
-
測試配置化
測試配置化能讓用戶使用和維護更加簡單、大部分情況下只需要維護配置腳本即可
注重細節提高問題定位能力
每個產品都有自身的特點,如果只是粗略的使用這些開源工具,可能達不到想要的效果,需要根據自身的情況選擇合理的工具并進行一定的調優。只有不斷提高自動化測試的問題定位能力,才能真正發揮自動化的價值。
利用開源力量、合理搭配使用
- 如果遇到問題,請尋找解決思路
- 根據思路尋找開源支持
- 如果找不到請參照第一條
開源世界已經有很多優秀的資源,不建議從頭開開始造輪子,除非你能很好的維護下去。基于現有的優秀工具、庫、平臺,針對自身產品的特點進行優化和二次開發更有利于工具本身的發展。
總結
測試是研發重要環節,前端自動化測試雖然還在不斷探索但已經有很多優秀的工具和庫。
合理利用工具、針對性選擇、減小使用和維護成本。
參考資料: