wx 是一個不錯的微信應用框架,接口和網站作的也不錯,和wechat-api是相似的項目javascript
羣裏有人問哪一個好html
樸靈說:「不寫測試的項目都不是好項目」java
確實wx目前尚未測試,對於一個開源項目來講,沒有測試和代碼覆蓋率是不完善的,並且從技術選型來講,大可能是不敢選的。node
那麼Nodejs開源項目裏怎麼樣寫測試、CI和代碼測試覆蓋率呢?jquery
目前主流的就bdd和tdd,本身查一下差別git
推薦程序員
另外Jasmine也挺有名,angularjs用它,不過挺麻煩的,還有一個選擇是qunit,最初是爲jquery測試寫的,在nodejs裏用仍是以爲怪怪的。angularjs
若是想簡單能夠tap,它和tape很像,下文會有詳細說明github
mocha是tj寫的web
https://github.com/mochajs/mocha
var assert = require("assert") describe('truth', function(){ it('should find the truth', function(){ assert.equal(1, 1); }) })
斷言風格,這裏默認是assert,推薦使用chaijs這個模塊,它提供3種風格
rspec裏推薦用expect,其實看我的習慣
比較典型一個mocha例子
var assert = require('chai').assert; var expect = require('chai').expect; require('chai').should(); describe('Test', function(){ before(function() { // runs before all tests in this block }) after(function(){ // runs after all tests in this block }) beforeEach(function(){ // runs before each test in this block }) afterEach(function(){ // runs after each test in this block }) describe('#test()', function(){ it('should return ok when test finished', function(done){ assert.equal('sang_test2', 'sang_test2'); var foo = 'bar'; expect(foo).to.equal('bar'); done() }) }) })
說明
單元測試須要的各個模塊說明
更多的看 http://nodeonly.com/2014/11/24/mongoose-test.html
若是你想真正的玩敏捷,從用戶故事開始,那麼下面這2個庫很是必要
啊,黃瓜。。。。
tape是substack寫的測試框架
https://github.com/substack/tape
var test = require('tape').test; test('equivalence', function(t) { t.equal(1, 1, 'these two numbers are equal'); t.end(); });
tape是很是簡單的測試框架,核心價值觀是」Tests are code」,因此你能夠像代碼同樣跑測試,
好比
node test/test.js
寫個腳本就無比簡單了。固然若是你想加'test runner' 庫也有現成的。
TAP全稱是Test Anything Protocol
它是可靠性測試的一種(tried & true)實現
從1987就有了,有不少語言都實現了。
它說白點就是用賊簡單的方式來格式化測試結果,好比
TAP version 13 # equivalence ok 1 these two numbers are equal 1..1 # tests 1 # pass 1 # ok
好比node裏的實現https://github.com/isaacs/node-tap
var tap = require('tap') // you can test stuff just using the top level object. // no suites or subtests required. tap.equal(1, 1, 'check if numbers still work') tap.notEqual(1, 2, '1 should not equal 2') // also you can group things into sub-tests. // Sub-tests will be run in sequential order always, // so they're great for async things. tap.test('first stuff', function (t) { t.ok(true, 'true is ok') t.similar({a: [1,2,3]}, {a: [1,2,3]}) // call t.end() when you're done t.end() })
必定要區分tap和tape,不要弄混了
科普一下,CI = Continuous integration 持續集成
Martin Fowler對持續集成是這樣定義的:
持續集成是一種軟件開發實踐,即團隊開發成員常常集成他們的工做,一般每一個成員天天至少集成一次,也就意味着天天可能會發生屢次集成。每次集成都經過自動化的構建(包括編譯,發佈,自動化測試)來驗證,從而儘快地發現集成錯誤。許多團隊發現這個過程能夠大大減小集成的問題,讓團隊可以更快的開發內聚的軟件。
它能夠
要素
1.統一的代碼庫 2.自動構建 3.自動測試 4.每一個人天天都要向代碼庫主幹提交代碼 5.每次代碼遞交後都會在持續集成服務器上觸發一次構建 6.保證快速構建 7.模擬生產環境的自動測試 8.每一個人均可以很容易的獲取最新可執行的應用程序 9.每一個人都清楚正在發生的情況 10.自動化的部署
也就是說,測試不經過不能部署,只有提交到服務器上,就能夠自動跑測試,測試經過後,就能夠部署到服務器上了(注意是"staging", 而非"production")。
通常最常的ci軟件是jenkins
舉個你們熟悉的例子iojs開發中的持續集成就是用的jenkins
https://jenkins-iojs.nodesource.com/
jenkins是自建環境下用的比較多,若是是開源項目,推薦travis-ci
對開源項目作持續集成是免費的(非開源的好貴),因此在github集成的基本是最多的。
對nodejs支持的也很是好。
舉2個例子
近年隨着tdd/bdd,開源項目,和敏捷開發的火熱,程序員們再也不知足說,我貢獻了一個開源項目
要有高要求,我要加測試
要有更高要求,我要把每個函數都測試到,讓別人相信個人代碼沒有任何問題
上一小節講的ci,實際上解決了反覆測試的自動化問題。可是如何看個人程序裏的每個函數都測試了呢?
答案是測試覆蓋率
在nodejs裏,推薦istanbul
Istanbul - 官方介紹 a JS code coverage tool written in JS
它能夠經過3種途徑生成覆蓋報告
安裝
$ npm install -g istanbul
執行
$ istanbul cover my-test-script.js -- my test args
它會生成./coverage
目錄,這裏面就是測試報告
好比個人項目裏
./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly #MongooseDao() ✓ should return ok when record create ✓ should return ok when record delete fixture-user ✓ should return ok when record deleteById ✓ should return ok when record removeById ✓ should return ok when record getById ✓ should return ok when record getAll ✓ should return ok when record all ✓ should return ok when record query 8 passing (50ms) ============================================================================= Writing coverage object [/Users/sang/workspace/moa/mongoosedao/coverage/coverage.json] Writing coverage reports at [/Users/sang/workspace/moa/mongoosedao/coverage] ============================================================================= =============================== Coverage summary =============================== Statements : 47.27% ( 26/55 ) Branches : 8.33% ( 1/12 ) Functions : 60% ( 9/15 ) Lines : 47.27% ( 26/55 ) ================================================================================
默認,它會生成coverage.json和Icov.info,若是你想生成html也能夠的。
好比說,上面的結果47.27%是我測試覆蓋的佔比,即55個函數,個人測試裏只覆蓋了26個。
那麼我須要有地方可以展現出來啊
咱們以mongoosedao項目爲例,介紹一下如何集成測試,ci和測試覆蓋率
最終效果如圖
package.json裏定義自定義執行腳本
"scripts": { "start": "npm publish .", "test": "./node_modules/.bin/gulp", "mocha": "./node_modules/.bin/mocha -u bdd", "cov":"./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" },
除了start和test外,都是自定義任務,其餘都要加run命令
npm run mocha npm run cov
var gulp = require('gulp'); var watch = require('gulp-watch'); var path = 'test/**/*.js'; gulp.task('watch', function() { gulp.watch(['test/**/*.js', 'lib/*.js'], ['mocha']); }); var mocha = require('gulp-mocha'); gulp.task('mocha', function () { return gulp.src(path , {read: false}) // gulp-mocha needs filepaths so you can't have any plugins before it .pipe(mocha({reporter: 'spec'})); }); gulp.task('default',['mocha', 'watch']);
這樣就能夠執行gulp的時候,當文件變更,會自動觸發mocha測試,簡化每次都輸入npm test這樣的操做。
固然你能夠玩更多的gulp,若是不熟悉,參考
.travis.yml
項目根目錄下,和package.json平級
language: node_js repo_token: COVERALLS.IO_TOKEN services: mongodb node_js: - "0.12" - "0.11" - "0.10" script: npm run mocha after_script: npm run cov
說明
在travis-ci.org上,github受權,添加repo都比較簡單
添加以後,就能夠看到,好比
https://travis-ci.org/moajs/mongoosedao
travis-ci實際上根據github的代碼變更進行自動持續構建,可是有的時候它不必定更新,或者說,你須要手動選一下:
點擊# 10 passed
,這樣就能夠強制它手動集成了。
其餘都很簡單,注意替換COVERALLS.IO_TOKEN便可。
.coveralls.yml
https://coveralls.io/是一個代碼測試覆蓋率的網站,
nodejs下面的代碼測試覆蓋率,原理是經過istanbul生成測試數據,上傳到coveralls網站上,而後以badge的形式展現出來
好比
具體實踐和travis-ci相似,用github帳號登錄,而後添加repo,而後在項目根目錄下,和package.json平級,增長.coveralls.yml
service_name: travis-pro repo_token: 99UNur6O7ksBqiwgg1NG1sSFhmu78A0t7
在上,第一次添加repo,顯示的是「SET UP COVERALLS」,裏面有token,須要放到.coveralls.yml
裏,
若是成功提交了,就能夠看到數據了
[![Build Status](https://travis-ci.org/moajs/mongoosedao.png?branch=master)](https://travis-ci.org/moajs/mongoosedao) [![Coverage Status](https://coveralls.io/repos/moajs/mongoosedao/badge.png)](https://coveralls.io/r/moajs/mongoosedao)
它就會顯示以下
舉例:https://github.com/node-webot/wechat-api/blob/master/Makefile
TESTS = test/*.js REPORTER = spec TIMEOUT = 20000 ISTANBUL = ./node_modules/.bin/istanbul MOCHA = ./node_modules/mocha/bin/_mocha COVERALLS = ./node_modules/coveralls/bin/coveralls.js test: @NODE_ENV=test $(MOCHA) -R $(REPORTER) -t $(TIMEOUT) \ $(MOCHA_OPTS) \ $(TESTS) test-cov: @$(ISTANBUL) cover --report html $(MOCHA) -- -t $(TIMEOUT) -R spec $(TESTS) test-coveralls: @$(ISTANBUL) cover --report lcovonly $(MOCHA) -- -t $(TIMEOUT) -R spec $(TESTS) @echo TRAVIS_JOB_ID $(TRAVIS_JOB_ID) @cat ./coverage/lcov.info | $(COVERALLS) && rm -rf ./coverage test-all: test test-coveralls .PHONY: test
我我的更喜歡npm+gulp的寫法,老是有一種make是c裏古老的東東。。。
本文講了
全文完
歡迎關注個人公衆號【node全棧】