天天看點

前端代碼覆寫率工具istanbul一、安裝二、覆寫率測試三、覆寫率門檻四、與測試架構的結合五、忽略某些代碼

測試的時候,我們常常關心,是否所有代碼都測試到了。

這個名額就叫做“代碼覆寫率”(code coverage)。它有四個測量次元:

  • 行覆寫率(line coverage):是否每一行都執行了?
  • 函數覆寫率(function coverage):是否每個函數都調用了?
  • 分支覆寫率(branch coverage):是否每個if代碼塊都執行了?
  • 語句覆寫率(statement coverage):是否每個語句都執行了?

Istanbul 是 JavaScript 程式的代碼覆寫率工具,本文介紹它的用法。

這個軟體以土耳其最大城市伊斯坦布爾命名,因為土耳其地毯世界聞名,而地毯是用來覆寫的。

一、安裝

Istanbul 是一個 npm 子產品,安裝非常簡單,就一行指令。

$ npm install -g istanbul

二、覆寫率測試

來看一個例子,怎麼使用 Istanbul 。下面是腳本檔案 simple.js 。

var a = ;
var b = ;
if ((a + b) > ) {
console.log('more than two');
}
           

使用 istanbul cover 指令,就能得到覆寫率。

$ istanbul cover simple.js
===== Coverage summary =====
Statements : 75% ( 3/4 )
Branches : 50% ( 1/2 )
Functions : 100% ( 0/0 )
Lines : 75% ( 3/4 )
=============================
           

傳回結果顯示,simple.js 有4個語句(statement),執行了3個;有2個分支(branch),執行了1個;有0個函數,調用了0個;有4行代碼,執行了3行。

這條指令同時還生成了一個 coverage 子目錄,其中的 coverage.json 檔案包含覆寫率的原始資料,coverage/lcov-report 是可以在浏覽器打開的覆寫率報告,其中有詳細資訊,到底哪些代碼沒有覆寫到。

三、覆寫率門檻

完美的覆寫率當然是 100%,但是現實中很難達到。需要有一個門檻,衡量覆寫率是否達标。

istanbul check-coverage 指令用來設定門檻,同時檢查目前代碼是否達标。

ERROR: Coverage for statements (75%) does not meet global threshold (90%)

上面指令設定語句覆寫率的門檻是 90% ,結果就報錯了,因為實際覆寫率隻有75%。

除了百分比門檻,我們還可以設定絕對值門檻,比如隻允許有一個語句沒有被覆寫到。

上面指令使用負數,表示絕對值門檻。這樣一來,上面的例子就通過了覆寫率測試,不會再報錯了。

百分比門檻和絕對值門檻,可以結合使用。

上面指令設定了3個覆寫率門檻:5個語句、3個 if 代碼塊、100%的函數。注意,這三個門檻是”與”(and)的關系,隻要有一個沒有達标,就會報錯。

四、與測試架構的結合

實際開發時,istanbul 總是與測試架構結合使用,下面以常用的 Mocha 架構為例。

sqrt.js 是一個計算平方根的腳本。

var My = {
sqrt: function(x) {
if (x < ) throw new Error("負值沒有平方根");
return Math.exp(Math.log(x)/);
}
};
module.exports = My;
           

它的測試腳本 test.sqrt.js 放在 test 子目錄。

var chai = require('chai');
var expect = chai.expect;
var My = require('../sqrt.js');
describe("sqrt", function() {
    it("4的平方根應該等于2", function() {
        expect(My.sqrt()).to.equal();
    });
    it("參數為負值時應該報錯", function() {
        expect(function(){ My.sqrt(-); }).to.throw("負值沒有平方根");
    });
});
           

然後,執行下面的指令得到代碼覆寫率。

$ istanbul cover _mocha
// or
$ istanbul cover _mocha test/test.sqrt.js
sqrt
✓ 4的平方根應該等于2
✓ 參數為負值時應該報錯
2 passing (7ms)
===== Coverage summary =====
Statements : 100% ( 5/5 )
Branches : 100% ( 2/2 )
Functions : 100% ( 1/1 )
Lines : 100% ( 4/4 )
=============================
           

上面指令中,istanbul cover 指令後面跟的是 _mocha 指令,前面的下劃線是不能省略的。

因為,mocha 和 _mocha 是兩個不同的指令,前者會建立一個程序執行測試,而後者是在目前程序(即 istanbul 所在的程序)執行測試,隻有這樣, istanbul 才會捕捉到覆寫率資料。其他測試架構也是如此,必須在同一個程序執行測試。

如果要向 mocha 傳入參數,可以寫成下面的樣子。

$ istanbul cover _mocha -- tests/test.sqrt.js -R spec
           

上面指令中,兩根連詞線後面的部分,都會被當作參數傳入 Mocha 。如果不加那兩根連詞線,它們就會被當作 istanbul 的參數(參考連結1,2)。

如果想在浏覽器運作 Istanbul ,可以參考這篇文章。

五、忽略某些代碼

istanbul 提供注釋文法,允許某些代碼不計入覆寫率。

var object = parameter || /* istanbul ignore next */ {};
           

上面代碼是為 object 指定預設值(一個空對象)。如果由于種種原因,沒有為 object 為空對象的情況寫測試,可以用注釋,不将這種情況計入覆寫率。注意,注釋要寫在”或”運算符的後面。

/* istanbul ignore if */
if (hardToReproduceError)) {
return callback(hardToReproduceError);
}
           

上面代碼的 if 語句塊,在計算覆寫率的時候會被忽略。

繼續閱讀