我研究了一下最近常聽到的 javascript MVC framework,
接下來就分享一下我這一個月來學習 angularjs 與 unit test 的心得感想吧。
angularjs + jasmine + karma
javascrip unit testing 的工具非常多,因為太多了,我都採用 angularjs tutorial 裡面使用的 tool: jasmine test framework + karam test runner.
Test Framework - jasmine
jasmine 是個 javascript testing framework,在單元測試中的角色如同寫 c++ / java 時用到的 cppunit 與 junit 一樣,讓你方便地寫出 test cases、組合成 test suite、比較預期結果與實際結果、回報執行結果。jasmine 比較特別的是用 it() 來定義 test case,引導你要把要測試的行為用完整句子寫出來。如果你的作文能力不錯的話,真的能把 test case 寫得像文章一樣好讀。
describe('FizzBuzz', function() { it('outputs the original number if the input number is not multiple of 3 or 7, function() { expect(fizzbuzz(1)).toBe("1"); expect(fizzbuzz(2)).toBe("2"); expect(fizzbuzz(4)).toBe("4"); }); it('outputs "fizz" if the input number is multiple of 3', function() { expect(fizzbuzz(3)).toBe("fizz"); expect(fizzbuzz(6)).toBe("fizz"); expect(fizzbuzz(9)).toBe("fizz"); }); it('outputs "buzz" if the input number is multiple of 7', function() { expect(fizzbuzz(7)).toBe("buzz"); expect(fizzbuzz(14)).toBe("buzz"); expect(fizzbuzz(28)).toBe("buzz"); }); it('outputs "fizzbuzz" if the input number is multiple of 7 and 3', function() { expect(fizzbuzz(21)).toBe("fizzbuzz"); }); });
Test Runner - karma
以前用 C++ / C# / java 時都比較不會注意到 test runner 這件事,反正你用什麼 testing framework,就是要用專用的 test runner,IDE 裡也許有內建,所以無感於 test runner 的存在。但是做 UI javascript testing 時有個大不同,UI 上的 javacript 是要丟到瀏覽器上面跑的,怎麼丟給瀏覽器?要丟給哪些瀏覽器?Test runner 就是幫我們搞定這些事情。
我這次選用的 Karam test runner 很厲害,可以跟各種 testing framework 與瀏覽器整合,無論用 jasmine、mocha 或是其他 framework,要在 chrome、firefox、safari、ie 執行測試,karma 都可以搞定。karma 還有個很貼心的服務—偵測到檔案變更時它會自己重新執行所有 test cases,對 TDD 更方便了。
karam 一次幫我搞定四個瀏覽器,非常盡責 |
安裝 karma 請參考這裡,安裝完可以用 karma init 產生預設的 config 再來修改。
module.exports = function(config) { config.set({ basePath: '../', // 使用 jasmine test framework frameworks: ['jasmine'], // 哪些 file 要載入測試。陷阱注意:順序很重要 files: [ 'test/phantomjs-fix.js', 'js/angular.min.js', 'test/angular-mocks.js', 'js/volume_dialog.js', 'test/spec/*spec.js' ], // 產生 progress 訊息與 junit report reporters: ['progress', 'junit'], // junit report 檔案名稱 junitReporter: { outputFile: 'test-results.xml', suites: '' }, port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, // 要在哪些瀏覽器上面執行 browsers: ['Chrome', 'Firefox', 'Safari', 'PhantomJS'], singleRun: false }); };設定裡頭有兩個陷阱,一是一定要把 angular-mock.js 加入到 files 裡,二是 files 是有順序性的,angular.js 在前,angular-mock*.js 要在後。搞這個就搞死我了。
Angularjs Unit Test 到底怎麼寫
angularjs developer's guide 浮光掠影的解釋了 unit testing 要怎麼做。但看完一定沒法馬上動手寫,最有效的方法還是去找人做一遍給你看,哈!啪一下額頭就是 youtube,這個 Introduction to angularjs unit testing 很適合。
整合到 CI - 沒有 GUI怎麼辦?
要用 PhantomJS 執行 unit test,除了安裝 PhantomJS 外,還需要 karma-phantomjs-launcher。執行 karma 時可以用 karma start --browsers PhantomJS 指定只要用 PhantomJS
用 PhantomJS 執行測試通常也很容易撞到這座牆:PhantomJS 不支援 Function.bind() method。解法就是自己實做吧!
// phantomjs-fix.js
// phantomJs does not support bind().
// See https://github.com/ractivejs/ractive/issues/679
Function.prototype.bind = Function.prototype.bind || function (thisp) {
var fn = this;
return function () {
return fn.apply(thisp, arguments);
};
};
整合到 CI - 產生 junit report
最後,在安裝 karma-junit-reporter 並設定產生檔案的名稱就能產出xml report.
沒有留言:
張貼留言