-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Writing Tests
All tests are written using tap as our test framework.
Tests go in test/tap/name-of-test.js
, you can see boiler plate for this below.
All tests can be run directly with node test/tap/name-of-test.js
or exactly as the
larger npm test suite does with npm run tap test/tap/name-of-test.js
.
Some existing tests may require that you run test/tap/00-config-setup.js
once before
they will work. New tests should not require this.
If you don't need to do any setup or cleanup you can skip those steps.
'use strict'
var test = require('tap').test
var common = require('../common-npm.js')
function setup () {
cleanup()
…sync setup…
}
function cleanup () {
…sync cleanup…
}
test('setup', function (t) {
setup()
t.end()
})
test('name-of-group-of-tests', function (t) {
t.is(actual, expected, 'description of what this is testing')
t.done()
})
test('cleanup', function (t) {
cleanup()
t.end()
})
If you need files on disk as part of your test, we use tacks to handle that, the boiler plate above with tacks looks like:
'use strict'
var path = require('path')
var test = require('tap').test
var common = require('../common-npm.js')
var Tacks = require('tacks')
var File = Tacks.File
var Dir = Tacks.Dir
var Symlink = Tacks.Symlink
var testdir = path.join(__dirname, path.basename(__filename, '.js'))
var fixture = new Tacks(Dir({
'package.json': File({
name: 'my-example-package',
version: '1.0.0'
})
}))
function setup () {
cleanup()
fixture.create(testdir)
…any other sync setup…
}
function cleanup () {
…any other sync cleanup…
fixture.remove(testdir)
}
test('setup', function (t) {
setup()
t.end()
})
test('name-of-group-of-tests', function (t) {
t.is(actual, expected, 'description of what this is testing')
t.done()
})
test('cleanup', function (t) {
cleanup()
t.end()
})
If you're going to run npm commands (which unless you're writing a unit test, you will be), you do that as below, where you provide the npm command line as the first argument. Note that you almost always need a test directory to run commands like this from as you don't want to end up acting on npm's modules.
test('name-of-group-of-tests', function (t) {
common.npm(['install', '--argument=value', 'package'], {cwd: testdir}, function (err, code, stdout, stderr) {
if (err) throw err
if (stdout.trim()) t.comment(stdout.trim())
if (stderr.trim()) t.comment(stderr.trim())
t.is(code, 0, 'brief desc of what our npm command was supposed to do')
t.match(stdout, /some expected result/, 'got description of expected result')
t.done()
})
})
If you need to mock modules (by modules I mean anything you require
), you can use
require-inject.
Using it looks like:
test('name-of-group-of-tests', function (t) {
var gentlyRm = requireInject('../../path/to/module/being/tested.js', {
'mocked-module': {…mocked version…}
'../../path/to/mocked/module.js': {…mocked version…}
})
})
IMPORTANT: If you want to write unit tests for a function in any module
that requires lib/npm.js
you will need to call npm.load
before
requiring your module. A common way of doing this is:
var npm = require('../../lib/npm.js')
test('setup', function (t) {
npm.load({}, t.end)
})
test('name-of-group-of-tests', function (t) {
var myModule = require('../../lib/my-module.js')
…
})