Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

tap-producing test harness for node and browsers

License

NotificationsYou must be signed in to change notification settings

tape-testing/tape

Repository files navigation

TAP-producing test harness for node and browsers

github actionscoverageLicenseDownloads

npm badge

tape

example

vartest=require('tape');test('timing test',function(t){t.plan(2);t.equal(typeofDate.now,'function');varstart=Date.now();setTimeout(function(){t.equal(Date.now()-start,100);},100);});test('test using promises',asyncfunction(t){constresult=awaitsomeAsyncThing();t.ok(result);});
$ node example/timing.jsTAP version 13# timing testok 1 should be strictly equalnot ok 2 should be strictly equal  ---    operator: equal    expected: 100    actual:   107  ...1..2# tests 2# pass  1# fail  1

usage

You always need torequire('tape') in test files. You can run the tests by usual node means (require('test-file.js') ornode test-file.js).You can also run tests using thetape binary to utilize globbing, on Windows for example:

$ tape tests/**/*.js

tape's arguments are passed to theglob module.If you wantglob to perform the expansion on a system where the shell performs such expansion, quote the arguments as necessary:

$ tape'tests/**/*.js'$ tape"tests/**/*.js"

If you wanttape to error when no files are found, pass--strict:

$ tape --strict'tests/**/*.js'

Preloading modules

Additionally, it is possible to maketape load one or more modules before running any tests, by using the-r or--require flag. Here's an example that loadsbabel-register before running any tests, to allow for JIT compilation:

$ tape -r babel-register tests/**/*.js

Depending on the module you're loading, you may be able to parameterize it using environment variables or auxiliary files. Babel, for instance, will load options from.babelrc at runtime.

The-r flag behaves exactly like node'srequire, and uses the same module resolution algorithm. This means that if you need to load local modules, you have to prepend their path with./ or../ accordingly.

For example:

$ tape -r ./my/local/module tests/**/*.js

Please note that all modules loaded using the-r flag will runbefore any tests, regardless of when they are specified. For example,tape -r a b -r c will actually loada andcbefore loadingb, since they are flagged as required modules.

things that go well with tape

tape maintains a fairly minimal core. Additional features are usually added by using another module alongsidetape.

pretty reporters

The default TAP output is good for machines and humans that are robots.

If you want a more colorful / pretty output there are lots of modules on npm that will output something pretty if you pipe TAP into them:

To use them, trynode test/index.js | tap-spec or pipe it into one of the modules of your choice!

uncaught exceptions

By default, uncaught exceptions in your tests will not be intercepted, and will causetape to crash. If you find this behavior undesirable, usetape-catch to report any exceptions as TAP errors.

other

command-line flags

While running tests, top-level configurations can be passed via the command line to specify desired behavior.

Available configurations are listed below:

--require

Alias:-r

This is used to load modules before running tests and is explained extensively in thepreloading modules section.

--ignore

Alias:-i

This flag is used when tests from certain folders and/or files are not intended to be run.The argument is a path to a file that contains the patterns to be ignored.It defaults to.gitignore when passed with no argument.

tape -i .ignore'**/*.js'

An error is thrown if the specified file passed as argument does not exist.

--ignore-pattern

Same functionality as--ignore, but passing the pattern directly instead of an ignore file.If both--ignore and--ignore-pattern are given, the--ignore-pattern argument is appended to the content of the ignore file.

tape --ignore-pattern'integration_tests/**/*.js''**/*.js'

--no-only

This is particularly useful in a CI environment where anonly test is not supposed to go unnoticed.

By passing the--no-only flag, any existingonly test causes tests to fail.

tape --no-only**/*.js

Alternatively, the environment variableNODE_TAPE_NO_ONLY_TEST can be set totrue to achieve the same behavior; the command-line flag takes precedence.

methods

The assertion methods intape are heavily influenced or copied from the methods innode-tap.

vartest=require('tape')

test([name], [opts], cb)

Create a new test with an optionalname string and optionalopts object.cb(t) fires with the new test objectt once all preceding tests have finished.Tests execute serially.

Availableopts options are:

  • opts.skip = true/false. See test.skip.
  • opts.timeout = 500. Set a timeout for the test, after which it will fail. See test.timeoutAfter.
  • opts.objectPrintDepth = 5. Configure max depth of expected / actual object printing. Environmental variableNODE_TAPE_OBJECT_PRINT_DEPTH can set the desired default depth for all tests; locally-set values will take precedence.
  • opts.todo = true/false. Test will be allowed to fail.

If you forget tot.plan() out how many assertions you are going to run and you don't callt.end() explicitly, or return a Promise that eventually settles, your test will hang.

Ifcb returns a Promise, it will be implicitly awaited. If that promise rejects, the test will be failed; if it fulfills, the test will end. Explicitly callingt.end() while also returning a Promise that fulfills is an error.

test.skip([name], [opts], cb)

Generate a new test that will be skipped over.

test.onFinish(fn)

The onFinish hook will get invoked when ALLtape tests have finished right beforetape is about to print the test summary.

fn is called with no arguments, and its return value is ignored.

test.onFailure(fn)

The onFailure hook will get invoked whenever anytape tests has failed.

fn is called with no arguments, and its return value is ignored.

t.plan(n)

Declare thatn assertions should be run.t.end() will be called automatically after thenth assertion.If there are any more assertions after thenth, or aftert.end() is called, they will generate errors.

t.end(err)

Declare the end of a test explicitly. Iferr is passed int.end will assert that it is falsy.

Do not callt.end() if your test callback returns a Promise.

t.teardown(cb)

Register a callback to run after the individual test has completed. Multiple registered teardown callbacks will run in order. Useful for undoing side effects, closing network connections, etc.

t.fail(msg)

Generate a failing assertion with a messagemsg.

t.pass(msg)

Generate a passing assertion with a messagemsg.

t.timeoutAfter(ms)

Automatically timeout the test after X ms.

t.skip(msg)

Generate an assertion that will be skipped over.

t.ok(value, msg)

Assert thatvalue is truthy with an optional description of the assertionmsg.

Aliases:t.true(),t.assert()

t.notOk(value, msg)

Assert thatvalue is falsy with an optional description of the assertionmsg.

Aliases:t.false(),t.notok()

t.error(err, msg)

Assert thaterr is falsy. Iferr is non-falsy, use itserr.message as the description message.

Aliases:t.ifError(),t.ifErr(),t.iferror()

t.equal(actual, expected, msg)

Assert thatObject.is(actual, expected) with an optional description of the assertionmsg.

Aliases:t.equals(),t.isEqual(),t.strictEqual(),t.strictEquals(),t.is()

t.notEqual(actual, expected, msg)

Assert that!Object.is(actual, expected) with an optional description of the assertionmsg.

Aliases:t.notEquals(),t.isNotEqual(),t.doesNotEqual(),t.isInequal(),t.notStrictEqual(),t.notStrictEquals(),t.isNot(),t.not()

t.looseEqual(actual, expected, msg)

Assert thatactual == expected with an optional description of the assertionmsg.

Aliases:t.looseEquals()

t.notLooseEqual(actual, expected, msg)

Assert thatactual != expected with an optional description of the assertionmsg.

Aliases:t.notLooseEquals()

t.deepEqual(actual, expected, msg)

Assert thatactual andexpected have the same structure and nested values usingnode's deepEqual() algorithm with strict comparisons (===) on leaf nodes and an optional description of the assertionmsg.

Aliases:t.deepEquals(),t.isEquivalent(),t.same()

t.notDeepEqual(actual, expected, msg)

Assert thatactual andexpected do not have the same structure and nested values usingnode's deepEqual() algorithm with strict comparisons (===) on leaf nodes and an optional description of the assertionmsg.

Aliases:t.notDeepEquals,t.notEquivalent(),t.notDeeply(),t.notSame(),t.isNotDeepEqual(),t.isNotDeeply(),t.isNotEquivalent(),t.isInequivalent()

t.deepLooseEqual(actual, expected, msg)

Assert thatactual andexpected have the same structure and nested values usingnode's deepEqual() algorithm with loose comparisons (==) on leaf nodes and an optional description of the assertionmsg.

t.notDeepLooseEqual(actual, expected, msg)

Assert thatactual andexpected do not have the same structure and nested values usingnode's deepEqual() algorithm with loose comparisons (==) on leaf nodes and an optional description of the assertionmsg.

t.throws(fn, expected, msg)

Assert that the function callfn() throws an exception.expected, if present, must be aRegExp,Function, orObject. TheRegExp matches the string representation of the exception, as generated byerr.toString(). For example, if you setexpected to/user/, the test will pass only if the string representation of the exception contains the worduser. Any other exception will result in a failed test. TheFunction could be the constructor for the Error type thrown, or a predicate function to be called with that exception.Object in this case corresponds to a so-called validation object, in which each property is tested for strict deep equality. As an example, see the following two tests--each passes a validation object tot.throws() as the second parameter. The first test will pass, because all property values in the actual error object are deeply strictly equal to the property values in the validation object.

    const err = new TypeError("Wrong value");    err.code = 404;    err.check = true;    // Passing test.    t.throws(        () => {            throw err;        },        {            code: 404,            check: true        },        "Test message."    );

This next test will fail, because all property values in the actual error object arenot deeply strictly equal to the property values in the validation object.

    const err = new TypeError("Wrong value");    err.code = 404;    err.check = "true";    // Failing test.    t.throws(        () => {            throw err;        },        {            code: 404,            check: true // This is not deeply strictly equal to err.check.        },        "Test message."    );

This is very similar to how Node'sassert.throws() method tests validation objects (please see theNodeassert.throws() documentation for more information).

Ifexpected is not of typeRegExp,Function, orObject, or omitted entirely, any exception will result in a passed test.msg is an optional description of the assertion.

Please note that the second parameter,expected, cannot be of typestring. If a value of typestring is provided forexpected, thent.throws(fn, expected, msg) will execute, but the value ofexpected will be set toundefined, and the specified string will be set as the value for themsg parameter (regardless of whatactually passed as the third parameter). This can cause unexpected results, so please be mindful.

t.doesNotThrow(fn, expected, msg)

Assert that the function callfn() does not throw an exception.expected, if present, limits what should not be thrown, and must be aRegExp orFunction. TheRegExp matches the string representation of the exception, as generated byerr.toString(). For example, if you setexpected to/user/, the test will fail only if the string representation of the exception contains the worduser. Any other exception will result in a passed test. TheFunction is the exception thrown (e.g.Error). Ifexpected is not of typeRegExp orFunction, or omitted entirely, any exception will result in a failed test.msg is an optional description of the assertion.

Please note that the second parameter,expected, cannot be of typestring. If a value of typestring is provided forexpected, thent.doesNotThrows(fn, expected, msg) will execute, but the value ofexpected will be set toundefined, and the specified string will be set as the value for themsg parameter (regardless of whatactually passed as the third parameter). This can cause unexpected results, so please be mindful.

t.test(name, [opts], cb)

Create a subtest with a new test handlest fromcb(st) inside the current testt.cb(st) will only fire whent finishes. Additional tests queued up aftert will not be run until all subtests finish.

You may pass the same options thattest() accepts.

t.comment(message)

Print a message without breaking the tap output.(Useful when using e.g.tap-colorize where output is buffered &console.log will print in incorrect order vis-a-vis tap output.)

Multiline output will be split by\n characters, and each one printed as a comment.

t.match(string, regexp, message)

Assert thatstring matches the RegExpregexp. Will fail when the first two arguments are the wrong type.

t.doesNotMatch(string, regexp, message)

Assert thatstring does not match the RegExpregexp. Will fail when the first two arguments are the wrong type.

t.capture(obj, method, implementation = () => {})

Replacesobj[method] with the supplied implementation.obj must be a non-primitive,method must be a valid property key (string or symbol), andimplementation, if provided, must be a function.

Calling the returnedresults() function will return an array of call result objects.The array of calls will be reset whenever the function is called.Call result objects will match one of these forms:

  • { args: [x, y, z], receiver: o, returned: a }
  • { args: [x, y, z], receiver: o, threw: true }

The replacement will automatically be restored on test teardown.You can restore it manually, if desired, by calling.restore() on the returned results function.

Modeled aftertap.

t.captureFn(original)

Wraps the supplied function.The returned wrapper has a.calls property, which is an array that will be populated with call result objects, described undert.capture().

Modeled aftertap.

t.intercept(obj, property, desc = {}, strictMode = true)

Similar tot.capture()``, but can be used to track get/set operations for any arbitrary property. Calling the returnedresults()` function will return an array of call result objects.The array of calls will be reset whenever the function is called.Call result objects will match one of these forms:

  • { type: 'get', value: '1.2.3', success: true, args: [x, y, z], receiver: o }
  • { type: 'set', value: '2.4.6', success: false, args: [x, y, z], receiver: o }

IfstrictMode istrue, andwritable isfalse, and noget orset is provided, an exception will be thrown whenobj[property] is assigned to.IfstrictMode isfalse in this scenario, nothing will be set, but the attempt will still be logged.

Providing bothdesc.get anddesc.set are optional and can still be useful for logging get/set attempts.

desc must be a valid property descriptor, meaning thatget/set are mutually exclusive withwritable/value.Additionally, explicitly settingconfigurable tofalse is not permitted, so that the property can be restored.

t.assertion(fn, ...args)

If you want to write your own custom assertions, you can invoke these conveniently using this method.

functionisAnswer(value,msg){// eslint-disable-next-line no-invalid-thisthis.equal(value,42,msg||'value must be the answer to life, the universe, and everything');};test('is this the answer?',(t)=>{t.assertion(isAnswer,42);// passes, default messaget.assertion(isAnswer,42,'what is 6 * 9?');// passes, custom messaget.assertion(isAnswer,54,'what is 6 * 9!');// fails, custom messaget.end();});

var htest = test.createHarness()

Create a new test harness instance, which is a function liketest(), but with a new pending stack and test state.

By default the TAP output goes toconsole.log(). You can pipe the output to someplace else if youhtest.createStream().pipe() to a destination stream on the first tick.

test.only([name], [opts], cb)

Liketest([name], [opts], cb) except if you use.only this is the only test case that will run for the entire process, all other test cases usingtape will be ignored.

Check out how the usage ofthe --no-only flag could help ensure there is no.only test running in a specified environment.

var stream = test.createStream(opts)

Create a stream of output, bypassing the default output stream that writes messages toconsole.log(). By defaultstream will be a text stream of TAP output, but you can get an object stream instead by settingopts.objectMode totrue.

tap stream reporter

You can create your own custom test reporter using thiscreateStream() api:

vartest=require('tape');varpath=require('path');test.createStream().pipe(process.stdout);process.argv.slice(2).forEach(function(file){require(path.resolve(file));});

You could substituteprocess.stdout for whatever other output stream you want, like a network connection or a file.

Pass in test files to run as arguments:

$ node tap.js test/x.js test/y.jsTAP version 13# (anonymous)not ok 1 should be strictly equal  ---    operator: equal    expected:"boop"    actual:"beep"  ...# (anonymous)ok 2 should be strictly equalok 3 (unnamed assert)# wheeeok 4 (unnamed assert)1..4# tests 4# pass  3# fail  1

object stream reporter

Here's how you can render an object stream instead of TAP:

vartest=require('tape');varpath=require('path');test.createStream({objectMode:true}).on('data',function(row){console.log(JSON.stringify(row))});process.argv.slice(2).forEach(function(file){require(path.resolve(file));});

The output for this runner is:

$ node object.js test/x.js test/y.js{"type":"test","name":"(anonymous)","id":0}{"id":0,"ok":false,"name":"should be strictly equal","operator":"equal","actual":"beep","expected":"boop","error":{},"test":0,"type":"assert"}{"type":"end","test":0}{"type":"test","name":"(anonymous)","id":1}{"id":0,"ok":true,"name":"should be strictly equal","operator":"equal","actual":2,"expected":2,"test":1,"type":"assert"}{"id":1,"ok":true,"name":"(unnamed assert)","operator":"ok","actual":true,"expected":true,"test":1,"type":"assert"}{"type":"end","test":1}{"type":"test","name":"wheee","id":2}{"id":0,"ok":true,"name":"(unnamed assert)","operator":"ok","actual":true,"expected":true,"test":2,"type":"assert"}{"type":"end","test":2}

A convenient alternative to achieve the same:

// report.jsvartest=require('tape');test.createStream({objectMode:true}).on('data',function(row){console.log(JSON.stringify(row))// for example});

and then:

$ tape -r ./report.js**/*.test.js

install

Withnpm do:

npm install tape --save-dev

troubleshooting

Sometimest.end() doesn’t preserve the expected output ordering.

For instance the following:

vartest=require('tape');test('first',function(t){setTimeout(function(){t.ok(1,'first test');t.end();},200);t.test('second',function(t){t.ok(1,'second test');t.end();});});test('third',function(t){setTimeout(function(){t.ok(1,'third test');t.end();},100);});

will output:

ok 1 second testok 2 third testok 3 first test

becausesecond andthird assumefirst has ended before it actually does.

Uset.plan() instead to let other tests know they should wait:

var test = require('tape');test('first', function (t) {+  t.plan(2);  setTimeout(function () {    t.ok(1, 'first test');-    t.end();  }, 200);  t.test('second', function (t) {    t.ok(1, 'second test');    t.end();  });});test('third', function (t) {  setTimeout(function () {    t.ok(1, 'third test');    t.end();  }, 100);});

license

MIT


[8]ページ先頭

©2009-2025 Movatter.jp