AVA实践:面向未来的Node.js测试运行器
2016-05-26 14:47
846 查看
ava-practice
![](https://github.com/avajs/ava/raw/master/media/header.png)
ava 是什么?
面向未来的测试运行器https://github.com/avajs/ava
简单的说ava是mocha的替代品,
es6语法支持更好,对aysnc/await有支持
执行效率更高,使用io并发,就必须保证测试的原子性
语义上更简单,集众家之长
虽然 JavaScript 是单线程,但在 Node.js 里由于其异步的特性使得 IO 可以并行。AVA 利用这个优点让你的测试可以并发执行,这对于 IO 繁重的测试特别有用。另外,测试文件可以在不同的进程里并行运行,让每一个测试文件可以获得更好的性能和独立的环境。在 Pageres 项目中从 Mocha切换 到 AVA 让测试时间从 31 秒下降到 11 秒。测试并发执行强制你写原子测试,意味着测试不需要依赖全局状态或者其他测试的状态,这是一件非常好的事情。
为什么要用 AVA?
轻量和高效简单的测试语法
并发运行测试
强制编写原子测试
没有隐藏的全局变量
为每个测试文件隔离环境
用 ES2015 编写测试
支持 Promise
支持 Generator
支持 Async
支持 Observable
强化断言信息
可选的 TAP 输出显示
简明的堆栈跟踪
AVS VS Mocha
origin
断言
ava支持的断言都比较简单,总体来说是抄自tap和tape,除了plan方法外。.pass([message])
Passing assertion.
.fail([message])
Failing assertion.
.truthy(value, [message])
Assert that value is truthy.
.falsy(value, [message])
Assert that value is falsy.
.true(value, [message])
Assert that value is true.
.false(value, [message])
Assert that value is false.
.is(value, expected, [message])
Assert that value is equal to expected.
.not(value, expected, [message])
Assert that value is not equal to expected.
.deepEqual(value, expected, [message])
Assert that value is deep equal to expected.
.notDeepEqual(value, expected, [message])
Assert that value is not deep equal to expected.
.throws(function|promise, [error, [message]])
Assert that function throws an error, or promise rejects with an error.
error can be a constructor, regex, error message or validation function.
Returns the error thrown by function or the rejection reason of promise.
.notThrows(function|promise, [message])
Assert that function doesn't throw an error or promise resolves.
.regex(contents, regex, [message])
Assert that contents matches regex.
.ifError(error, [message])
Assert that error is falsy.
自定义断言
使用node.js sdk里默认的assertimport assert from 'assert'; test(t => { assert(true); });
使用chai断言库,支持3种风格
import test from 'ava'; var assert = require('chai').assert; var expect = require('chai').expect; var should = require('chai').should(); test('expect with chai', t => { // typeof expect('test').to.be.a('string'); expect({ foo: 'bar' }).to.be.an('object'); expect(null).to.be.a('null'); expect(undefined).to.be.an('undefined'); expect(new Error).to.be.an('error'); expect(new Float32Array()).to.be.a('float32array'); expect(Symbol()).to.be.a('symbol'); }); test('should with chai', t => { var foo = 'bar' var tea = { flavors:[1,2,2] } foo.should.be.a('string'); foo.should.equal('bar'); foo.should.have.length(3); tea.should.have.property('flavors') .with.length(3); }); test('assert with chai', t => { var foo = 'bar' var tea = { flavors:[1,2,2] } assert.typeOf(foo, 'string'); assert.equal(foo, 'bar'); assert.lengthOf(foo, 3) assert.property(tea, 'flavors'); assert.lengthOf(tea.flavors, 3); });
hook
test方法默认是顺序执行,如果里面是顺序执行的,那么它是正常的。如果里面是异步方法呢?结果是test执行完了,而异步方法还在跑,这样的结果是,这个测试怎么跑都是正确的,因为没有走断言。。。。演示代码如下
test('#register()', t => { // 此方法是异步的,保存需要时间 user.save((err, u) => { console.log(err) console.log('u=' + u) t.true(u.password.length > 50) }) });
当test完成,user.save还没完成,结果0断言,测试结果显示成功。。。这是非常典型的例子。
最简单的回调,注意写法,
test.cb意味着这是需要调用
t.end()才能结束,对于测试异步方法非常好用
test.cb('#register()', t => { // 此方法是异步的,保存需要时间 user.save((err, u) => { console.log(err) console.log('u=' + u) t.true(u.password.length > 50) t.end() }) });
t.end() 结束异步调用,仅仅在test.cb()方法里有效
下面例子中,保证在测试save方法之前,执行完成before。也就是说,执行before等待2秒,然后再开始跑其他测试。
test.before.cb((t) => { setTimeout(() => { t.end(); }, 2000); }); test('#save()', t => { let user = new User({ username: 'i5ting', password: '0123456789' }); user.save((err, u) => { if (err) log(err) t.is(u.username, 'i5ting'); }); });
其他cb方法可依此类推
Control flow
PromiseGenerator
Async/await
Promise 支持
If you return a promise in the test you don't need to explicitly end the test as it will end when the promise resolves.test(t => { return somePromise().then(result => { t.is(result, 'unicorn'); }); });
Generator 函数支持
AVA comes with built-in support for generator functions.test(function * (t) { const value = yield generatorFn(); t.true(value); });
具体在mongoose里的generator里使用
test('#save()', function * (t) { var u = yield User.create(user) t.is(u.username, 'i5ting'); });
测试console.log或者其他终端输出内容,推荐使用co-exec,然后将结果正则匹配就好了
import test from 'ava'; var exec = require('co-exec'); test('exec()', function * (t) { var commit = yield exec('ls -alt|grep .gitignore|wc -l'); console.log(commit) t.true(commit == 1); }); test('exec2()', function * (t) { var result = yield exec('ls -alt') console.log(result.trim().match(/(gitignore)/)) t.true(result.trim().match(/(gitignore)/).length > 1); t.regex(result, /(gitignore)/); });
还有一个断言t.regex,不过不太容易判断
Async/await支持
AVA comes with built-in support for async functions (async/await).test(async function (t) { const value = await promiseFn(); t.true(value); }); // async arrow function test(async t => { const value = await promiseFn(); t.true(value); });
db
每次连接数据库成功后,最好是dropDatabase
var mongoose = require("mongoose"); // 核心代码,是否开启测试 mongoose.set('debug', false); var db = mongoose.connect("mongodb://127.0.0.1:27017/db_helloworld"); db.connection.on("error", function (error) { console.log("数据库连接失败:" + error); }); db.connection.on("open", function () { console.log("数据库连接成功"); mongoose.connection.db.dropDatabase(); });
测试覆盖率
https://github.com/bcoe/nycJust install both:
$ npm install --save-dev nyc ava
They you can add this to package.json:
"scripts": { "test": "nyc ava" }
集成其他badge也很简单,看它的文档即可
使用ava的开源项目推荐
找这类的项目最好是从ava开始,找贡献的相关作者,从这些作者的项目里找,基本上是十有八九。pageres
postcss
cssnano
postcss-discard-comments
postcss-selector-parser
文档地址
ava-practice带左侧目录网页版本
ava-practice源码,以后文档会在github上持续更新
欢迎反馈,pr、star
全文完
相关文章推荐
- node更新版本后sass无法编译解决办法
- node.js学习
- Swap Nodes in Pairs(交换链表相邻的两个结点)
- 25. Reverse Nodes in k-Group
- leetcode---Swap Nodes in Pairs
- node
- Nodejs正则表达式函数之match、test、exec、search、split、replace使用详解
- NodeJs初学者经典入门解析
- Elasticsearch NoNodeAvailableException 问题解决
- nodejs安装
- nodejs MODEL层 封装(一)
- 222. Count Complete Tree Nodes
- Yslow on Nodejs server
- DOMNodeInserted监听div内容改变
- node+fis3搭建
- hadoop2.5集群迁移namenode
- nodejs 返回html页面--使用 ejs 模板
- nodejs
- leetcode 19. Remove Nth Node From End of List
- leetcode 25. Reverse Nodes in k-Group——很值得一看的链表题