用覆蓋率測試可以檢查目前所做的測試,是否有涵蓋到伺服器程式原始碼的各個地方,這樣才知道是否有遺漏掉、沒有測試到的邏輯。
可用工具
之前的測試都是利用nodeunit框架來執行,所以要跑測試覆蓋率,除了檢測覆蓋率的工具,最好還要能跟nodeunit做整合。
express framework, jade template engine, expreeso test framework等等著名套件的作者TJ Holowaychuk(https://github.com/visionmedia),有開發一個測試覆蓋率的工具:node-jscoverage。看起來也沒太多選擇,所以就先拿這個來用。
安裝會有點麻煩...因為沒有預先編譯好的執行檔,好像也沒有包好的原始碼...所以只好上github硬碰硬
git clone https://github.com/visionmedia/node-jscoverage.git
來複製git repository使用上到是很簡單,假設需要做覆蓋率的程式目錄為:lib,jscoverage處理過得目錄為:lib-cov,那只要用這兩個參數來執行jscoverage:
jscoverage lib lib-cov
就可以了,jscoverage會利用lib中的程式,產生具有覆蓋率資訊的程式版本,然後存放在lib-cov目錄。基本上它就是在程式的每一行插上一行統計資訊程式,之後測試程式使用的模組/伺服器程式必須改使用lib-cov中的同名程式,函授利用專門處理這些資訊的報表程式,就可以產出覆蓋率測試的報告。
實作
nodeunit並沒有內建處理jscoverage的程式,這部份需要額外下載,並且加工...因為我找到的報表程式有點舊
npm install -g nodeunit-coverage
指令來安裝3.1.2 line 14: sys模組已經改名了,所以改成:
sys = require('util'),
3.1.3 line 16: 改成:
AssertionError = require('nodeunit/lib/assert').AssertionError,
3.1.4 line 23: 雖然不是必要,但是改一下以資識別:
exports.info = "jscoverage reporter";
3.1.5 line 61之後: 其實我只需要覆蓋率的資訊,所以註解掉位於moduleStart、testDone、done三個函數中的程式碼,只留下三行:
if ($jscoverage) {
reportCoverage($jscoverage);
}
3.2 dep\coverage.js
3.2.1 line 3: 改成:
var sys = require('util');
3.2.2 line 5: 用ant跑的話,有utf8符號或console顏色碼都會有問題,所以改成:
var boring = true;
3.2.3 line 14: 這一段會造成輸出順序的問題,所以應該改成:
sys.print(colorize(str));
修改之後,使用ant coverage
就可以看到測試結果:
不過結果太寬,console塞不下...只好另外利用ant寫簡單的cov-report target,把測試結果輸出到reports/coverage.log中。利用ant cov-report
就可以把結果輸出到reports目錄,然後用文字編輯器來開啟:
這樣看起來比較好看。可以看到tools.js的覆蓋率只到35%,這是因為tools.hostHandler等函數中有許多部分沒有做測試,另外,也沒有針對一些例外情況作測試。這些就是將來需要補強的地方。往下就可以看到所有程式的覆蓋率結果:
第一欄是行號,第二欄是執行次數,第三欄是程式碼。所以看到執行次數是0的時候,就知道這一行程式在測試中沒有跑到。
現在build.xml長這樣(超過字數,所以請上github):
https://github.com/fillano/evolve/blob/23b0c1372e415cf903be529902394cda70b8eb0c/build.xml
另外附上我自己編譯的jscoverage.exe,如果有編譯的困難的話,可以先用這個。
今天的範例檔fillano-evolve-v0.0.13-0-g23b0c13.zip,目前版本是v0.0.13。