幾個前端技術框架(工具)

jopen 10年前發布 | 37K 次閱讀 前端 前端技術

不曉得有多少人在做前端技術開發,問過在我之后加入公司的,或者面試過的前端工程師,幾乎都沒有在寫前端技術。他們有的來自于百度,新浪,SAP 等。當然,我在這不能以偏概全,寫了Testing的不情愿來也說不一定。半年前,我還沒受TW的影響,無聊中在看過jQuery的Testing之后有 了一些Testing方面的思考,開始嘗試地去為我的各種庫加單元Testing。那時候接觸到的唯一一個Testing框架就是QUnit

QUnit不但是我接觸到的第一個前端框架,也是那時候了解的最全面的單元Testing框架,超越了對JUnit和NUnit(后兩個只是蜻蜓點水般玩了下)。在完成功能之后加上Testing,然后看Testing通過,然后開心地又加幾個功能,再寫幾個Testing,那種感覺說不出的爽。

我把前端技術分成兩個大類,一類是使用js開發的模塊,偏向邏輯的單元Testing,比如前端MVC中的Controller的 Testing,JS類庫(underscore、jQuery、Wind.js)的Testing。另一類是UI組件的Testing,因為UI一般包 含了標記、事件處理、動畫、樣式等元素,Testing將會變成功能Testing,甚至是集成Testing。而且因為含有標記,樣式和復雜的事件處 理,不能使用自動化Testing百分百模擬人工操作,所以做這一類的Testing比較難一些。據我所知,現在的前端開發Testing框架數QUnit、Jasmine、Mocha、JsTestDriver這四個比較出名,用來寫Testing都是很上手的。

QUnit

QUnit是XUnit系列在前端技術領域中的后繼者,提供了單一的testcase的寫法和assert斷言方式,結構十分簡單。詳細的介紹可以在官網介紹頁面找到,其所有的assert斷言方式也可以斷言列表中查看。

QUnit編寫的單元Testing可以在瀏覽器和Nodejs進行Testing,由于QUnit提供了非常華麗的瀏覽器報表樣式,個人還是推薦QUnit用例放在瀏覽器中跑。

QUnit自身沒有提供任何Spy,Stub和mock的技術,所以在集成Testing方面比其他框架要弱,可以使用第三方的Testing類庫幫助,比如Sinon.js,是一個獨立的Testing幫助類庫,以后寫文章詳細介紹。

Jasmine

Jasmine號稱自己是行為驅動 Testing(BDD)框架,語法和RSpec幾乎一樣,用describe描述Suites,用it描述一個Testing用例。在單元 Testing中,一般一個Suite用來描述一個類,或者一個含有多個Testing用例的方法。Jasmine中提供了有語義的斷言方式,使用 expect和not的鏈式調用。看看下面這個case就能了解到Testing寫起來也可以很優雅。

it("and can have a negative case", function() {   expect(false).not.toBe(true);});

Jasmine和QUnit一樣,可以在Nodejs環境和瀏覽器中執行,在Nodejs環境中有很多NPM包可以使用,比如jasmine-node。在公司接觸到的Rails項目,基本上都是集成jasmine來做前端技術,傳統運行界面比較丑,可以試試有所改善standalone版本。如果想在jasmine中TestingUI操作,可以使用jasmine-jquery,它提供了載入fixture的功能,并且自定義了很多斷言中使用到的matchers,比如斷言一個元素是否有某個樣式可以這么寫:

expect($('#target')).toHaveCss({margin: "10px"});

Jasmine提供了spy方法,可以通過它創建fake方法調用,從而斷言方法是否被調用,被調用多少次,或者驗證接受的參數是否正確等等。另 外,使用spy對象的andCallFake方法也能發揮一些stub的作用。之前提到的Sinon.js同樣可以和Jasmine配合使用。

一切都看上還挺順利的,不過有兩個地方我對jasmine不是很爽,一個就是非常ugly的異步Testing,如果在代碼Testing中間遇到 了異步調用,就需要用到waitsFor方法,此方法接受一個方法,當方法返回true時運行異步調用之后部分,因為異步調用不會阻塞代碼運行,所以必須 使用一個runs方法把之后部分包住,超過兩次的異步調用會導致寫出來的代碼各種讓人看不懂,這一點還不如QUnit的stop和start方法易懂好 用,在Mocha中的異步Testing也 優雅得多。另一個是發生在TestingUI組件時,因為所有Testing都會在同一個文件中運行,而且需要預先把Testing的樣式和腳本資源都載 入到頁面中,先不說樣式之間會相互影響導致斷言失敗的問題,在Testing過程中如果存在動態創建元素到頁面的情況可能會導致回收fixture時忽略 掉新創建的元素導致錯誤。我期望的UITesting是為每case提供獨立的運行環境,首先解決了樣式沖突問題,每個UI組件Testing運行的環境 只含有為case準備的樣式和腳本,我有想過用父子頁面實現,腳本在父窗口中運行,操作子窗口中的UI組件。而且,新元素的回收問題在每次子窗口重載UI 組件的時候也得到解決。

這是我覺得ugly的一個Testing

describe("Asynchronous specs", function() {   var value, flag;  
  it("should support async execution of test preparation and exepectations", function() {  
    runs(function() {  flag = false;  value = 0;  
      setTimeout(function() {flag = true;  }, 500);});  
    waitsFor(function() {  value++;  return flag;}, "The Value should be incremented", 750);  
    runs(function() {  expect(value).toBeGreaterThan(0);});  
  });});

Mocha

摩卡coffee,香飄四溢。當我第一 次接觸到它的時候,我果斷放棄了Jasmine,我說放棄是心里上放棄了,因為Mocha主打Nodejs環境,雖也弱弱地支持瀏覽器運行,但在瀏覽器端 運行和Jasmine比較沒有多大優勢,但Mocha在Nodejs上的運行比Jasmine-node好出很多,而且支持多種報表的輸出,不僅有優秀的 字體著色和報錯顯示,還有些非常有趣,比如飛機從左飛行到右的進度條提示。特別有用的還有json和html格式的jscoverage報表。我的Mr.Coverage就是使用的html格式的報表。

Mocha的語法和Jasmine幾乎一樣,有時甚至支持直接跑Jasmine的Testing。它支持三種斷言方式,包括QUnit的assert方式、Jasmine的expect方式,另一種是更具語義的方式should.js,最后一種也是我最喜歡的一種,它的實現強烈推薦去看看。使用should可以看到一些DSL的影子。寫法十分優雅呢,使我愛不釋手。在這里需要提到一個非常優秀的斷言類庫Chaijs,使用它可以讓Testing框架支持assert、expect、should三種斷言方式。并沒試過在QUnit里面使用Chaijs,從文檔上看應該是支持的。

var user = {name: 'tj'   , pets: ['tobi', 'loki', 'jane', 'bandit']};  
user.should.have.property('name', 'tj'); user.should.have.property('pets').with.lengthOf(4);

Mocha并沒有自己提供什么spy,stub,mockTesting技術,官方也推薦直接使用sinon.js。

在Nodejs中運行Testing時候都需要運行命令,每次修改代碼后都需要重新運行命令,Mocha里面提供了watch的功能,當文件修改之后都會自動運行Testing。

如果是在瀏覽器中運行,那么會遇上一個更大的麻煩之處,就是瀏覽器兼容性Testing,在每次修改代碼之后,為了保證每個瀏覽器都能運行通過,所 以需要每個瀏覽器都刷新一下。想想都覺得程序員浪費時間在這些地方太不值得了。JsTestDriver可以幫我們解決這個問題。

JsTestDriver

JsTestDriver是Google大神的作品,說它是一個框架,不如說它是一個Testing工具。JsTestDriver使用Java打造,所有的使用都是從JsTestDriver.jar包 開始的,使用它需要先啟動一個server,需要進行Testing的瀏覽器先要連接到此server,然后運行testcase,所有瀏覽器都會響應。 每次修改代碼之后就不用每個瀏覽器都刷新了,運行命令行就可以了,如果你使用了watch的話,那所有case都會自動在瀏覽器中運行了。

JsTestDriver并沒有什么優雅的語法,斷言方式也普普通通,一切都顯得非常實在。同時,JsTestDriver還提供了另外一個jar包可以使用它輸入代碼的行Testing覆蓋率,和現有的項目集成使用是十分方便的。

由于JsTestDriver先啟用了Testing服務器,所以可以使用它來做遠程Testing,比如可以利用它來做產品或者類產品環境的Testing。

Google的MVC框架AngularJS就是使用JsTestDriver進行Testing的,而且在Testing中載入頁面時確實是使用一個iframe載入Testing的UI和資源,讓case運行在一個獨立的環境,解決了我在Jasmine UI組件Testing中遇到的沖突問題。

 

對前端UI組件Testing,我一直有個疑問,當我需要斷言一個樣式是否存在一個樣式時,是去斷言此元素是否含有一個實現此樣式的class呢, 還是直接斷言元素的此樣式是否存在。比如在Testingpopup彈出框時,在彈出狀態下是驗證display屬性還是驗證彈出框有沒有一個名為 show的class。因為我覺得有show這個class不一定能代表彈出框一定處于顯示狀態,所以偏向于直接斷言display屬性。有人說我關注點 太奇怪,但我其實是在想如何能讓Testing更能準確地起到驗證的效果這個大問題。我承認世事無絕對,自動化Testing永遠不能完全代替人工 Testing,尤其顏色、視覺的部分更需要人眼去測。只希望在做類似的Testing時能多想想,尤其是UX設計人員一定要求實現的點。

以上就是我對四種Testing框架或工具的簡介,相互比較之后,如果選擇在Nodejs環境中使用,首當其沖我推薦Mocha,如果需要在瀏覽器 中運行,那么可以選擇Jasmine或者JsTestDriver工具。但是工具的選擇并不是提高軟件質量的原因,你所編寫的高質量Testing才是。 要寫出高質量的Testing,驅動出可被Testing的代碼,必須懂得如何劃分task,如何理解Testing技術給軟件帶來的好處,如何編寫高質 量的單元Testing等等。這些能力和前端后端無關,他們是需要在Testing領域長期摸索才能練就的本領。希望好學者能飽讀書籍,熟能生巧。在下也 才剛剛上路。

來源:非常UED

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!