面向未来的测试运行器
简单的说ava是mocha的替代品,
虽然 JavaScript 是单线程,但在 Node.js 里由于其异步的特性使得 IO 可以并行。AVA 利用这个优点让你的测试可以并发执行,这对于 IO 繁重的测试特别有用。另外,测试文件可以在不同的进程里并行运行,让每一个测试文件可以获得更好的性能和独立的环境。在 Pageres 项目中从 Mocha切换 到 AVA 让测试时间从 31 秒下降到 11 秒。测试并发执行强制你写原子测试,意味着测试不需要依赖全局状态或者其他测试的状态,这是一件非常好的事情。
ava支持的断言都比较简单,总体来说是抄自tap和tape,除了plan方法外。
Passing assertion.
Failing assertion.
Assert that value is truthy.
Assert that value is falsy.
Assert that value is true.
Assert that value is false.
Assert that value is equal to expected.
Assert that value is not equal to expected.
Assert that value is deep equal to expected.
Assert that value is not deep equal to expected.
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.
Assert that function doesn’t throw an error or promise resolves.
Assert that contents matches regex.
Assert that error is falsy.
使用node.js sdk里默认的assert
import 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);
});
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()
})
});
下面例子中,保证在测试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方法可依此类推
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');
});
});
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,不过不太容易判断
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);
});
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();
});
Just install both:
$ npm install --save-dev nyc ava
They you can add this to package.json:
"scripts": {
"test": "nyc ava"
}
集成其他badge也很简单,看它的文档即可
找这类的项目最好是从ava开始,找贡献的相关作者,从这些作者的项目里找,基本上是十有八九。
欢迎反馈,pr、star
全文完
欢迎关注我的公众号【node全栈】