m(icro)test is a lightweight test runner for node.js written in es6+ (~4kb).
thanks for your support! gratipay
install m.test directly from npm to project's devDependencies.
npm install --save-dev m.test
test files are run by simply passing them to node. for a given test/index.js
run the following command to execute the suite:
node test
run the following one to enable node's debugger:
node debug test
more utilities to run your suites are available through the cli. if no files are given they will be looked up from ./test
recursively.
m.test [options] [files]
when executing suites through the cli m.test
will be assigned to global.test
by design. the following line can be omitted:
const {test} = require('m.test')
further instructions can be accessed via --help
flag and man-pages by executing either m.test --help
or man m.test
within your shell.
const {ok} = require('assert')
test('it just works!', function () {
ok(true)
})
const {ok} = require('assert')
test('it works async too!', function (done) {
setTimeout(function () {
ok(true)
done()
}, 0)
})
test('done takes a error argument!', function (done) {
setTimeout(function (err = null) {
done(err)
}, 0)
})
test('runner works with Promise', function (done) {
let promise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(true)
}, 0)
})
promise.then(result => {
ok(result)
done()
})
})
test('can be used as a context', function () {
test('works!', function (done) {
done(null)
})
test('works!', function (done) {
done(null)
})
})
const {test: context, test: describe, test: it} = require('m.test')
context('given some context', function () {
describe('your subject', function () {
it('just works!', (done) => done(null))
})
})
test('description', function (done) {
done(null)
})
beforeEach(done => setup(done))
afterEach(done => teardown(done))
it is important to call beforeEach
and afterEach
wrap functions after test
functions themselves. when using wraps within nested suites consider their contextual binding.
test('description 1', function () {
test('description 1.1', Function.prototype)
test('description 1.2', Function.prototype)
beforeEach(done => setup(done))
afterEach(done => teardown(done))
})
test('description 2', function () {
test('description 2.1', Function.prototype)
test('description 2.2', Function.prototype)
})
(in the example above hooks would be called for 1.1
e 1.2
)
test.skip('description', function () {
// this function will never be called
})
the skip modifier comes with an optional doSkip=true
parameter that enables/disables the skip behavior according to the expression:
test.skip('description', function () {
// this test will be skipped when NODE_ENV=CI
}, /CI/gi.test(process.env.NODE_ENV))
test.timeout('description', function () {
// this test will fail if it exceeds 200ms of execution
}, 200)
the timeout modifier comes with an optional doTimeout=true
parameter that enables/disables the timeout behavior according to the expression:
test.timeout('description', function () {
// this test will have a timeout when NODE_ENV=CI
}, 200, /CI/g.test(process.env.NODE_ENV))