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
里,
若是成功提交了,就能够看到数据了
[](https://travis-ci.org/moajs/mongoosedao) [](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全栈】