- 正確性:測試可以驗證程式碼的正確性,在上線前做到心裡有底
- 自動化:當然手工也可以測試,通過console可以列印出內部資訊,但是這是一次性的事情,下次測試還需要從頭來過,效率不能得到保證。通過編寫測試用例,可以做到一次編寫,多次執行
- 解釋性:測試用例用於測試介面、模組的重要性,那麼在測試用例中就會涉及如何使用這些API。其他開發人員如果要使用這些API,那閱讀測試用例是一種很好地途徑,有時比文件說明更清晰
- 驅動開發,指導設計:程式碼被測試的前提是程式碼本身的可測試性,那麼要保證程式碼的可測試性,就需要在開發中注意API的設計,TDD將測試前移就是起到這麼一個作用
- 保證重構:網際網路行業產品迭代速度很快,迭代後必然存在程式碼重構的過程,那怎麼才能保證重構後程式碼的質量呢?有測試用例做後盾,就可以大膽的進行重構
2.1 測試框架
目前,前端的測試框架很多,像QUnit、jasmine、mocha、jest、intern等框架,這些框架各有特點,簡單描述下,感興趣的可以具體研究:
- Qunit: 該框架誕生之初是為了jquery的單元測試,後來獨立出來不再依賴於jquery本身,但是其身上還是脫離不開jquery的影子
- jasmine: Behavior-Drive development(BDD)風格的測試框架,在業內較為流行,功能很全面,自帶asssert、mock功能
- mocha: node社群大神tj的作品,可以在node和browser端使用,具有很強的靈活性,可以選擇自己喜歡的斷言庫,選擇測試結果的report
- intern: 看官方介紹該測試框架功能極其全面,似乎囊括了業內跟測試相關的所有功能
- chai:應該是目前組流行的斷言庫了,支援TDD(assert)、BDD(expect、should)兩個風格的斷言庫
var chai = require('chai'); var assert = chai.assert; // typef assert === 'object' chai.should(); // 對Obejct.prototype進行擴充
2.3 mock庫
先來說說為什麼需要mock吧:需要測試的單元依賴於外部的模組,而這些依賴的模組具有一些特點,例如不能控制、實現成本較高、操作危險等原因,不能直接使用依賴的模組,這樣情況下就需要對其進行mock,也就是偽造依賴的模組。例如在使用XMLHttpRequest時,需要模擬http statusCode為404的情況,這種情況實際很難發生,必然要通過mock來實現測試。
- sinon.js: 目前使用最多的mock庫,將其分為spies、stub、fake XMLHttpRequest、Fake server、Fake time幾種,根據不同的場景進行選擇。
- karma: 設定測試需要的框架、環境、原始檔、測試檔案等,配置完後,就可以輕鬆地執行測試。
- 測試框架:判斷內部是否存在異常,存在則console出對應的text資訊
- 斷言庫:當actual值與expect值不一樣時,就丟擲異常,供外部測試框架檢測到,這就是為什麼有些測試框架可以自由選擇斷言庫的原因,只要可以丟擲異常,外部測試框架就可以工作。
- mock函式:建立一個新的函式,用這個函式來取代原來的函式,同時在這個新函式上新增一些額外的屬性,例如called、calledWithArguments等資訊
function describe (text, fn) { try { fn.apply(...); } catch(e) { assert(text) } } function fn () { while (...) { beforeEach(); it(text, function () { assert(); }); afterEach(); } } function it(text, fn) { ... fn(text) ... } function assert (expect, actual) { if (expect not equla actual ) { throw new Error(text); } } function fn () { ... } function spy(cb) { var proxy = function () { ... } proxy.called = false; proxy.returnValue = '...'; ... return proxy; } var proxy = spy(fn); // 得到一個mock函式
4.如何寫單元測試用例
4.1原則
- 測試程式碼時,只考慮測試,不考慮內部實現
- 資料儘量模擬現實,越靠近現實越好
- 充分考慮資料的邊界條件
- 對重點、複雜、核心程式碼,重點測試
- 利用AOP(beforeEach、afterEach),減少測試程式碼數量,避免無用功能
- 測試、功能開發相結合,有利於設計和程式碼重構
一句話簡單來說,就是先寫測試,後寫功能實現。TDD的目的是通過測試用例來指引實際的功能開發,讓開發人員首先站在全域性的視角來看待需求。具體定義可以檢視維基;
就個人而言,TDD不是一個技術,而是一種開發的指導思想。在目前網際網路的開發環境下,業務開發很難做到TDD開發,一是因為需要更多時間編寫單元測試用例;二是要求非常瞭解業務需求;三是要求開發人員有很強的程式碼設計能力。但是當我們寫元件、工具方法、類庫的時候,TDD就可以得到很好地使用。
4.3 BDD
行為驅動開發要求更多人員參與到軟體的開發中來,鼓勵開發者、QA、相關業務人員相互協作。BDD是由商業價值來驅動,通過使用者介面(例如GUI)理解應用程式。詳見維基.
相關閱讀
評論(1)