前端單元測試總結及測試工具介紹

 1.爲何須要單元測試

  • 正確性:測試能夠驗證代碼的正確性,在上線前作到內心有底
  • 自動化:固然手工也能夠測試,經過console能夠打印出內部信息,可是這是一次性的事情,下次測試還須要從頭來過,效率不能獲得保證。經過編寫測試用例,能夠作到一次編寫,屢次運行
  • 解釋性:測試用例用於測試接口、模塊的重要性,那麼在測試用例中就會涉及如何使用這些API。其餘開發人員若是要使用這些API,那閱讀測試用例是一種很好地途徑,有時比文檔說明更清晰
  • 驅動開發,指導設計:代碼被測試的前提是代碼自己的可測試性,那麼要保證代碼的可測試性,就須要在開發中注意API的設計,TDD將測試前移就是起到這麼一個做用
  • 保證重構:互聯網行業產品迭代速度很快,迭代後必然存在代碼重構的過程,那怎麼才能保證重構後代碼的質量呢?有測試用例作後盾,就能夠大膽的進行重構

  2.前端相關的單元測試技術

  2.1 測試框架php

  目前,前端的測試框架不少,像QUnit、jasmine、mocha、jest、intern等框架,這些框架各有特色,簡單描述下,感興趣的能夠具體研究:html

  • Qunit: 該框架誕生之初是爲了jquery的單元測試,後來獨立出來再也不依賴於jquery自己,可是其身上仍是脫離不開jquery的影子
  • jasmine: Behavior-Drive development(BDD)風格的測試框架,在業內較爲流行,功能很全面,自帶asssert、mock功能
  • mocha: node社區大神tj的做品,能夠在node和browser端使用,具備很強的靈活性,能夠選擇本身喜歡的斷言庫,選擇測試結果的report
  • intern: 看官方介紹該測試框架功能極其全面,彷佛囊括了業內跟測試相關的全部功能

  2.2 斷言庫前端

  • chai:應該是目前組流行的斷言庫了,支持TDD(assert)、BDD(expect、should)兩個風格的斷言庫
    var chai = require('chai'); 
    
    var assert = chai.assert; // typef assert === 'object'
    chai.should(); // 對Obejct.prototype進行拓展
  •  should.js: TJ的另一個開源貢獻
  • expect.js:BDD風格的另一個斷言庫,基於should.js,是mini版的BDD庫
  • assert(node自帶核心模塊): 能夠在node中使用的斷言模塊

  2.3 mock庫node

  先來講說爲何須要mock吧:須要測試的單元依賴於外部的模塊,而這些依賴的模塊具備一些特色,例如不能控制、實現成本較高、操做危險等緣由,不能直接使用依賴的模塊,這樣狀況下就須要對其進行mock,也就是僞造依賴的模塊。例如在使用XMLHttpRequest時,須要模擬http statusCode爲404的狀況,這種狀況實際很難發生,必然要經過mock來實現測試。jquery

  • sinon.js: 目前使用最多的mock庫,將其分爲spies、stub、fake XMLHttpRequest、Fake server、Fake time幾種,根據不一樣的場景進行選擇。

  2.4 test runnergit

  • karma: 設置測試須要的框架、環境、源文件、測試文件等,配置完後,就能夠輕鬆地執行測試。

  3.單元測試技術的實現原理

  1. 測試框架:判斷內部是否存在異常,存在則console出對應的text信息
  2. 斷言庫:當actual值與expect值不同時,就拋出異常,供外部測試框架檢測到,這就是爲何有些測試框架能夠自由選擇斷言庫的緣由,只要能夠拋出異常,外部測試框架就能夠工做。
  3. 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原則github

  • 測試代碼時,只考慮測試,不考慮內部實現
  • 數據儘可能模擬現實,越靠近現實越好
  • 充分考慮數據的邊界條件
  • 對重點、複雜、核心代碼,重點測試
  • 利用AOP(beforeEach、afterEach),減小測試代碼數量,避免無用功能
  • 測試、功能開發相結合,有利於設計和代碼重構

  4.2 TDDapi

  一句話簡單來講,就是先寫測試,後寫功能實現。TDD的目的是經過測試用例來指引實際的功能開發,讓開發人員首先站在全局的視角來看待需求。具體定義能夠查看維基;app

  就我的而言,TDD不是一個技術,而是一種開發的指導思想。在目前互聯網的開發環境下,業務開發很難作到TDD開發,一是由於須要更多時間編寫單元測試用例;二是要求很是瞭解業務需求;三是要求開發人員有很強的代碼設計能力。可是當咱們寫組件工具方法、類庫的時候,TDD就能夠獲得很好地使用。框架

  4.3 BDD

  行爲驅動開發要求更多人員參與到軟件的開發中來,鼓勵開發者、QA、相關業務人員相互協做。BDD是由商業價值來驅動,經過用戶接口(例如GUI)理解應用程序。詳見維基.

相關文章
相關標籤/搜索