Simple setup/teardowns and assertion extensions for the tape testing framework
tape is a very simple, minimalist testing framework. Sometimes, however, you'd like there to be a little bit more functionality in the way of setup and teardown functions (or beforeEach and afterEach functions in BDD speak).
This module is installed via npm, and requires tape
as a peerDependency:
$ npm install tape redtape
There are two ways to use redtape, one uses an options object, while the other uses function parameters:
You can pass in an optional beforeEach/afterEach on an options object to the
redtape
function which will be called before every test:
var redtape = require('redtape'),
fs = require('fs');
var test = redtape({
beforeEach: function (cb) {
fs.writeFile('/tmp/myfile.txt', 'my data', cb);
},
afterEach: function (cb) {
fs.unlink('/tmp/myfile.txt', cb);
}
});
test('I should be able to read a file', function (t) {
t.plan(1);
fs.readFile('/tmp/myfile.txt', { encoding: 'utf8' }, function (err, data) {
if (err) return t.error(err);
t.equal(data, 'my data');
});
});
// You can also pass the test plan assertion in as the second argument
// ie. This is equivalent to the test above
test('I should be able to read a file', 1, function (t) {
fs.readFile('/tmp/myfile.txt', { encoding: 'utf8' }, function (err, data) {
if (err) return t.error(err);
t.equal(data, 'my data');
});
});
You can extend the test t
object by passing through an asserts
key on
the options object to the redtape
function with an object that will be
used to extend the built in t
object:
var redtape = require('redtape'),
fs = require('fs');
var test = redtape({
beforeEach: function (cb) {
fs.writeFile('/tmp/myfile.txt', 'my data', cb);
},
afterEach: function (cb) {
fs.unlink('/tmp/myfile.txt', cb);
},
// add the `like` function to the `t` test object
asserts: {
like: function (str, reg, msg) {
this.ok(reg.test(str), msg);
}
}
});
test('I should be able to read a file', function (t) {
t.plan(1);
fs.readFile('/tmp/myfile.txt', { encoding: 'utf8' }, function (err, data) {
if (err) return t.error(err);
t.like(data, /data/);
});
});
If you pass through addition data in the beforeEach
callback, this data will
get passed as additional parameters to the test, as well as to the afterEach
function for cleanup:
var redtape = require('redtape'),
level = require('level'),
rimraf = require('rimraf');
var test = redtape({
beforeEach: function (cb) {
rimraf.sync('/tmp/mytestdb');
// the level callback returns a handle to the open database for it's first
// non error argument
level('/tmp/mytestdb', cb);
},
// because the beforeEach function returns a variable, the afterEach function
// will also get a handle to the data so it can clean up.
afterEach: function (db, cb) {
db.close(cb);
}
});
test('I should be able to read a file', function (t, db) {
t.plan(3);
db.put('my key', 'my value', function (err) {
t.error(err);
db.get('my key', function (err, data) {
t.error(err);
t.equal(data, 'my value');
});
});
});
You can pass in an optional beforeEach/afterEach to the redtape
function
which will be called before every test:
var redtape = require('redtape'),
fs = require('fs');
var test = redtape(beforeEach, afterEach);
function beforeEach(cb) {
fs.writeFile('/tmp/myfile.txt', 'my data', cb);
}
function afterEach(cb) {
fs.unlink('/tmp/myfile.txt', cb);
}
test('I should be able to read a file', function (t) {
t.plan(1);
fs.readFile('/tmp/myfile.txt', { encoding: 'utf8' }, function (err, data) {
if (err) return t.error(err);
t.equal(data, 'my data');
});
});
You can extend the test t
object by passing through a third argument to the
redtape
function with an object that will be used to extend the built in
t
object:
var redtape = require('redtape'),
fs = require('fs');
// add the `like` function to the `t` test object
var assertions = {
like: function (str, reg, msg) {
this.ok(reg.test(str), msg);
}
};
var test = redtape(beforeEach, afterEach, assertions);
function beforeEach(cb) {
fs.writeFile('/tmp/myfile.txt', 'my data', cb);
}
function afterEach(cb) {
fs.unlink('/tmp/myfile.txt', cb);
}
test('I should be able to read a file', function (t) {
t.plan(1);
fs.readFile('/tmp/myfile.txt', { encoding: 'utf8' }, function (err, data) {
if (err) return t.error(err);
t.like(data, /data/);
});
});
If you pass through addition data in the beforeEach
callback, this data will
get passed as additional parameters to the test, as well as to the afterEach
function for cleanup:
var redtape = require('redtape'),
level = require('level'),
rimraf = require('rimraf');
var test = redtape(beforeEach, afterEach);
function beforeEach(cb) {
rimraf.sync('/tmp/mytestdb');
// the level callback returns a handle to the open database for it's first
// non error argument
level('/tmp/mytestdb', cb);
}
// because the beforeEach function returns a variable, the afterEach function
// will also get a handle to the data so it can clean up.
function afterEach(db, cb) {
db.close(cb);
}
test('I should be able to read a file', function (t, db) {
t.plan(3);
db.put('my key', 'my value', function (err) {
t.error(err);
db.get('my key', function (err, data) {
t.error(err);
t.equal(data, 'my value');
});
});
});
Using the .only
variant will only run that particular test case:
var redtape = require('redtape');
var testCount = 0;
var test = redtape();
test('this test will not run', function (t) {
testCount++;
t.fail('this test should never run');
t.end();
});
// only this test will run
test.only('can use a simple after each function with 1 callback', function (t) {
testCount++;
t.equal(testCount, 1, 'only test should be run');
t.end();
});
test('this test will also not run', function (t) {
testCount++;
t.fail('this test should also never run');
t.end();
});
Similarly, you can ignore a test by adding the .ignore
suffix:
var redtape = require('redtape');
var testCount = 0;
var test = redtape();
test.ignore('this test will not run', function (t) {
testCount++;
t.fail('this test should never run');
t.end();
});
test('this test case will run', function (t) {
testCount++;
t.equal(testCount, 1, 'only one test should run');
t.end();
});