Extremely lightweight JavaScript test coverage
Refactor safely -- without configuring a burdensome test suite
Need to test JavaScript for browsers? Use feather-test-browser
$ npm install feather-test --save-dev
myProject/test/specs/one.spec.js
describe('gizmo is a mogwai', function () {
describe('when you feed him after midnight', function () {
describe('he becomes a gremlin', function (expect) {
expect(skin).not.toBe('furry');
expect(temperament).toContain('angry');
expect(explosions).toBeGreaterThan(99, 'explosions caused by gremlins');
});
});
});
myProject/test/specs/two.spec.js
// example of an asynchronous test
describe('teddy ruxpin is the creepiest bear ever', function () {
describe('he blinks twice every 3 seconds', function (expect, done) {
activateTeddy();
setTimeout(function () {
expect(timesBlinked).toBe(4);
done();
}, 6000);
});
});
myProject/package.json
{
"scripts": {
"test": "node ./test/run"
}
}
myProject/
|--test/
| |--specs/
| | |--one.spec.js
| | |--two.spec.js
| |--run.js
|--src/
| |--etc.
|--package.json
myProject/test/run.js
var FeatherTest = require('feather-test');
// create a new FeatherTest with your spec files
var myTests = new FeatherTest({
helpers: './helpers',
specs: './specs'
});
// run all queued tests by calling `run`
// (optional callback will be executed after all tests finish)
myTests.run(callback);
$ cd myProject
$ npm test
// All 4 tests passed!
Any of the below can also be negated using not.toBe, etc.
- toBe
- toBeGreaterThan
- toBeLessThan
- toContain
- toEqual
- toHaveBeenCalled
- toHaveBeenCalledWith
The following methods are globally available within spec files
The basic building block of specs. A description explains what features will be tested within. (can be nested)
describe('some feature', function () {
describe('can do a thing', function (expect) {
expect(thing).toBe(true);
});
});
Skips this block and all assertions within. Also skips nested describes.
xdescribe('not right now', function (expect) {
expect(thisBlock).not.toBe('executed');
});
Alias for describe
(above). Added to make migrations easier
Use with matchers to indicate a match with and object that shares the same constructor
expect(result).toBe({
eventName: 'activated',
timestamp: any(Number)
});
Manage timing events. Installing will add a global override for setTimeout
and setInterval
. To advance the clock use clock.tick(amount)
.
describe('overrides setTimeout when installed', function (expect) {
clock.install();
let happened = 0;
setTimeout(function () {
happened++;
}, 2000);
expect(happened).toBe(0);
clock.tick(2000);
expect(happened).toBe(1);
clock.uninstall();
});
Stub or mock any function or method.
spy.on()
watches and counts each invocation.
describe('no double agents here', function (expect) {
let obj = {
method: function () {
return 'original';
}
};
expect(obj.method()).toBe('original');
describe('put on your disguise', function (expect) {
spy.on(obj, 'method', function () {
return 'impostor';
});
expect(obj.method()).toBe('impostor');
});
// spies are reset after the containing describe is done
expect(obj.method()).toBe('original');
});
spy()
creates a new spy.
describe('your secret training is complete', function (expect) {
let doubleOhSeven = spy(() => { return { license: 'kill'}; });
expect(doubleOhSeven().license).toBe('kill');
expect(doubleOhSeven).toHaveBeenCalled();
});
Pass a closured reference into async blocks to avoid having your spied functions reset.
var obj = {
method: function () {
console.log('original');
}
};
describe('test some stuff', function () {
describe('do something async', function () {
spy.on(obj, 'method', function () {
console.log('spied');
});
var spiedFn = obj.method; // save into a new reference that can be closured below
setTimeout(function () {
// must be used here as `spiedFn` not as `obj.method`
spiedFn(1); // output: "spied"
}, 10);
});
describe('do something async', function () {
obj.method(); // output: "original"
});
});
new FeatherTest(options)
Files (or a directory of files) to load before your specs
The files (or a directory of files) that contain your specs
A function to execute before each describe
A function to execute after each describe
An array of matchers to add to the expect() return object
customMatchers: [
{
name: 'toMatchCustom',
message: 'to match custom things',
matcher: function (expected, actual, utils) {
return expected === actual * 3;
}
}
]
If set to true
specs will halt execution after the first spec fails
How long (in ms) to wait for an async describe to call done()
We use Travis CI. Here's a link to the build: https://travis-ci.org/feather-test/feather-test