1 | # tape
|
2 |
|
3 | tap-producing test harness for node and browsers
|
4 |
|
5 | [![browser support](https://ci.testling.com/substack/tape.png)](http://ci.testling.com/substack/tape)
|
6 |
|
7 | [![build status](https://secure.travis-ci.org/substack/tape.svg?branch=master)](http://travis-ci.org/substack/tape)
|
8 |
|
9 | ![tape](http://substack.net/images/tape_drive.png)
|
10 |
|
11 | # example
|
12 |
|
13 | ``` js
|
14 | var test = require('tape');
|
15 |
|
16 | test('timing test', function (t) {
|
17 | t.plan(2);
|
18 |
|
19 | t.equal(typeof Date.now, 'function');
|
20 | var start = Date.now();
|
21 |
|
22 | setTimeout(function () {
|
23 | t.equal(Date.now() - start, 100);
|
24 | }, 100);
|
25 | });
|
26 | ```
|
27 |
|
28 | ```
|
29 | $ node example/timing.js
|
30 | TAP version 13
|
31 | # timing test
|
32 | ok 1 should be equal
|
33 | not ok 2 should be equal
|
34 | ---
|
35 | operator: equal
|
36 | expected: 100
|
37 | actual: 107
|
38 | ...
|
39 |
|
40 | 1..2
|
41 | # tests 2
|
42 | # pass 1
|
43 | # fail 1
|
44 | ```
|
45 |
|
46 | # usage
|
47 |
|
48 | You always need to `require('tape')` in test files. You can run the tests by
|
49 | usual node means (`require('test-file.js')` or `node test-file.js`). You can
|
50 | also run tests using the `tape` binary to utilize globbing, on Windows for
|
51 | example:
|
52 |
|
53 | ```sh
|
54 | $ tape tests/**/*.js
|
55 | ```
|
56 |
|
57 | `tape`'s arguments are passed to the
|
58 | [`glob`](https://www.npmjs.com/package/glob) module. If you want `glob` to
|
59 | perform the expansion on a system where the shell performs such expansion, quote
|
60 | the arguments as necessary:
|
61 |
|
62 | ```sh
|
63 | $ tape 'tests/**/*.js'
|
64 | $ tape "tests/**/*.js"
|
65 | ```
|
66 |
|
67 | ## Preloading modules
|
68 |
|
69 | Additionally, it is possible to make `tape` load one or more modules before running any tests, by using the `-r` or `--require` flag. Here's an example that loads [babel-register](http://babeljs.io/docs/usage/require/) before running any tests, to allow for JIT compilation:
|
70 |
|
71 | ```sh
|
72 | $ tape -r babel-register tests/**/*.js
|
73 | ```
|
74 |
|
75 | Depending on the module you're loading, you may be able to paramaterize it using environment variables or auxiliary files. Babel, for instance, will load options from [`.babelrc`](http://babeljs.io/docs/usage/babelrc/) at runtime.
|
76 |
|
77 | The `-r` flag behaves exactly like node's `require`, 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.
|
78 |
|
79 | For example:
|
80 |
|
81 | ```sh
|
82 | $ tape -r ./my/local/module tests/**/*.js
|
83 | ```
|
84 |
|
85 | Please note that all modules loaded using the `-r` flag will run *before* any tests, regardless of when they are specified. For example, `tape -r a b -r c` will actually load `a` and `c` *before* loading `b`, since they are flagged as required modules.
|
86 |
|
87 | # things that go well with tape
|
88 |
|
89 | tape maintains a fairly minimal core. Additional features are usually added by using another module alongside tape.
|
90 |
|
91 | ## pretty reporters
|
92 |
|
93 | The default TAP output is good for machines and humans that are robots.
|
94 |
|
95 | If you want a more colorful / pretty output there are lots of modules on npm
|
96 | that will output something pretty if you pipe TAP into them:
|
97 |
|
98 | - https://github.com/scottcorgan/tap-spec
|
99 | - https://github.com/scottcorgan/tap-dot
|
100 | - https://github.com/substack/faucet
|
101 | - https://github.com/juliangruber/tap-bail
|
102 | - https://github.com/kirbysayshi/tap-browser-color
|
103 | - https://github.com/gummesson/tap-json
|
104 | - https://github.com/gummesson/tap-min
|
105 | - https://github.com/calvinmetcalf/tap-nyan
|
106 | - https://www.npmjs.org/package/tap-pessimist
|
107 | - https://github.com/toolness/tap-prettify
|
108 | - https://github.com/shuhei/colortape
|
109 | - https://github.com/aghassemi/tap-xunit
|
110 | - https://github.com/namuol/tap-difflet
|
111 | - https://github.com/gritzko/tape-dom
|
112 | - https://github.com/axross/tap-diff
|
113 | - https://github.com/axross/tap-notify
|
114 | - https://github.com/zoubin/tap-summary
|
115 | - https://github.com/Hypercubed/tap-markdown
|
116 |
|
117 | To use them, try `node test/index.js | tap-spec` or pipe it into one
|
118 | of the modules of your choice!
|
119 |
|
120 | ## uncaught exceptions
|
121 |
|
122 | By default, uncaught exceptions in your tests will not be intercepted, and will cause tape to crash. If you find this behavior undesirable, use [tape-catch](https://github.com/michaelrhodes/tape-catch) to report any exceptions as TAP errors.
|
123 |
|
124 | ## other
|
125 |
|
126 | - CoffeeScript support with https://www.npmjs.com/package/coffeetape
|
127 | - Promise support with https://www.npmjs.com/package/blue-tape
|
128 | - ES6 support with https://www.npmjs.com/package/babel-tape-runner
|
129 |
|
130 | # methods
|
131 |
|
132 | The assertion methods in tape are heavily influenced or copied from the methods
|
133 | in [node-tap](https://github.com/isaacs/node-tap).
|
134 |
|
135 | ```
|
136 | var test = require('tape')
|
137 | ```
|
138 |
|
139 | ## test([name], [opts], cb)
|
140 |
|
141 | Create a new test with an optional `name` string and optional `opts` object.
|
142 | `cb(t)` fires with the new test object `t` once all preceeding tests have
|
143 | finished. Tests execute serially.
|
144 |
|
145 | Available `opts` options are:
|
146 | - opts.skip = true/false. See test.skip.
|
147 | - opts.timeout = 500. Set a timeout for the test, after which it will fail.
|
148 | See test.timeoutAfter.
|
149 | - opts.objectPrintDepth = 5. Configure max depth of expected / actual object
|
150 | printing.
|
151 |
|
152 | If you forget to `t.plan()` out how many assertions you are going to run and you
|
153 | don't call `t.end()` explicitly, your test will hang.
|
154 |
|
155 | ## test.skip(name, cb)
|
156 |
|
157 | Generate a new test that will be skipped over.
|
158 |
|
159 | ## test.onFinish(fn)
|
160 |
|
161 | The onFinish hook will get invoked when ALL tape tests have finished
|
162 | right before tape is about to print the test summary.
|
163 |
|
164 | ## t.plan(n)
|
165 |
|
166 | Declare that `n` assertions should be run. `t.end()` will be called
|
167 | automatically after the `n`th assertion. If there are any more assertions after
|
168 | the `n`th, or after `t.end()` is called, they will generate errors.
|
169 |
|
170 | ## t.end(err)
|
171 |
|
172 | Declare the end of a test explicitly. If `err` is passed in `t.end` will assert
|
173 | that it is falsey.
|
174 |
|
175 | ## t.fail(msg)
|
176 |
|
177 | Generate a failing assertion with a message `msg`.
|
178 |
|
179 | ## t.pass(msg)
|
180 |
|
181 | Generate a passing assertion with a message `msg`.
|
182 |
|
183 | ## t.timeoutAfter(ms)
|
184 |
|
185 | Automatically timeout the test after X ms.
|
186 |
|
187 | ## t.skip(msg)
|
188 |
|
189 | Generate an assertion that will be skipped over.
|
190 |
|
191 | ## t.ok(value, msg)
|
192 |
|
193 | Assert that `value` is truthy with an optional description of the assertion `msg`.
|
194 |
|
195 | Aliases: `t.true()`, `t.assert()`
|
196 |
|
197 | ## t.notOk(value, msg)
|
198 |
|
199 | Assert that `value` is falsy with an optional description of the assertion `msg`.
|
200 |
|
201 | Aliases: `t.false()`, `t.notok()`
|
202 |
|
203 | ## t.error(err, msg)
|
204 |
|
205 | Assert that `err` is falsy. If `err` is non-falsy, use its `err.message` as the
|
206 | description message.
|
207 |
|
208 | Aliases: `t.ifError()`, `t.ifErr()`, `t.iferror()`
|
209 |
|
210 | ## t.equal(actual, expected, msg)
|
211 |
|
212 | Assert that `actual === expected` with an optional description of the assertion `msg`.
|
213 |
|
214 | Aliases: `t.equals()`, `t.isEqual()`, `t.is()`, `t.strictEqual()`,
|
215 | `t.strictEquals()`
|
216 |
|
217 | ## t.notEqual(actual, expected, msg)
|
218 |
|
219 | Assert that `actual !== expected` with an optional description of the assertion `msg`.
|
220 |
|
221 | Aliases: `t.notEquals()`, `t.notStrictEqual()`, `t.notStrictEquals()`,
|
222 | `t.isNotEqual()`, `t.isNot()`, `t.not()`, `t.doesNotEqual()`, `t.isInequal()`
|
223 |
|
224 | ## t.deepEqual(actual, expected, msg)
|
225 |
|
226 | Assert that `actual` and `expected` have the same structure and nested values using
|
227 | [node's deepEqual() algorithm](https://github.com/substack/node-deep-equal)
|
228 | with strict comparisons (`===`) on leaf nodes and an optional description of the assertion `msg`.
|
229 |
|
230 | Aliases: `t.deepEquals()`, `t.isEquivalent()`, `t.same()`
|
231 |
|
232 | ## t.notDeepEqual(actual, expected, msg)
|
233 |
|
234 | Assert that `actual` and `expected` do not have the same structure and nested values using
|
235 | [node's deepEqual() algorithm](https://github.com/substack/node-deep-equal)
|
236 | with strict comparisons (`===`) on leaf nodes and an optional description of the assertion `msg`.
|
237 |
|
238 | Aliases: `t.notEquivalent()`, `t.notDeeply()`, `t.notSame()`,
|
239 | `t.isNotDeepEqual()`, `t.isNotDeeply()`, `t.isNotEquivalent()`,
|
240 | `t.isInequivalent()`
|
241 |
|
242 | ## t.deepLooseEqual(actual, expected, msg)
|
243 |
|
244 | Assert that `actual` and `expected` have the same structure and nested values using
|
245 | [node's deepEqual() algorithm](https://github.com/substack/node-deep-equal)
|
246 | with loose comparisons (`==`) on leaf nodes and an optional description of the assertion `msg`.
|
247 |
|
248 | Aliases: `t.looseEqual()`, `t.looseEquals()`
|
249 |
|
250 | ## t.notDeepLooseEqual(actual, expected, msg)
|
251 |
|
252 | Assert that `actual` and `expected` do not have the same structure and nested values using
|
253 | [node's deepEqual() algorithm](https://github.com/substack/node-deep-equal)
|
254 | with loose comparisons (`==`) on leaf nodes and an optional description of the assertion `msg`.
|
255 |
|
256 | Aliases: `t.notLooseEqual()`, `t.notLooseEquals()`
|
257 |
|
258 | ## t.throws(fn, expected, msg)
|
259 |
|
260 | Assert that the function call `fn()` throws an exception. `expected`, if present, must be a `RegExp` or `Function`. The `RegExp` matches the string representation of the exception, as generated by `err.toString()`. The `Function` is the exception thrown (e.g. `Error`). `msg` is an optional description of the assertion.
|
261 |
|
262 | ## t.doesNotThrow(fn, expected, msg)
|
263 |
|
264 | Assert that the function call `fn()` does not throw an exception. `msg` is an optional description of the assertion.
|
265 |
|
266 | ## t.test(name, [opts], cb)
|
267 |
|
268 | Create a subtest with a new test handle `st` from `cb(st)` inside the current
|
269 | test `t`. `cb(st)` will only fire when `t` finishes. Additional tests queued up
|
270 | after `t` will not be run until all subtests finish.
|
271 |
|
272 | You may pass the same options that [`test()`](#testname-opts-cb) accepts.
|
273 |
|
274 | ## t.comment(message)
|
275 |
|
276 | 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.)
|
277 |
|
278 | ## var htest = test.createHarness()
|
279 |
|
280 | Create a new test harness instance, which is a function like `test()`, but with
|
281 | a new pending stack and test state.
|
282 |
|
283 | By default the TAP output goes to `console.log()`. You can pipe the output to
|
284 | someplace else if you `htest.createStream().pipe()` to a destination stream on
|
285 | the first tick.
|
286 |
|
287 | ## test.only(name, cb)
|
288 |
|
289 | Like `test(name, cb)` except if you use `.only` this is the only test case
|
290 | that will run for the entire process, all other test cases using tape will
|
291 | be ignored
|
292 |
|
293 | ## var stream = test.createStream(opts)
|
294 |
|
295 | Create a stream of output, bypassing the default output stream that writes
|
296 | messages to `console.log()`. By default `stream` will be a text stream of TAP
|
297 | output, but you can get an object stream instead by setting `opts.objectMode` to
|
298 | `true`.
|
299 |
|
300 | ### tap stream reporter
|
301 |
|
302 | You can create your own custom test reporter using this `createStream()` api:
|
303 |
|
304 | ``` js
|
305 | var test = require('tape');
|
306 | var path = require('path');
|
307 |
|
308 | test.createStream().pipe(process.stdout);
|
309 |
|
310 | process.argv.slice(2).forEach(function (file) {
|
311 | require(path.resolve(file));
|
312 | });
|
313 | ```
|
314 |
|
315 | You could substitute `process.stdout` for whatever other output stream you want,
|
316 | like a network connection or a file.
|
317 |
|
318 | Pass in test files to run as arguments:
|
319 |
|
320 | ```
|
321 | $ node tap.js test/x.js test/y.js
|
322 | TAP version 13
|
323 | # (anonymous)
|
324 | not ok 1 should be equal
|
325 | ---
|
326 | operator: equal
|
327 | expected: "boop"
|
328 | actual: "beep"
|
329 | ...
|
330 | # (anonymous)
|
331 | ok 2 should be equal
|
332 | ok 3 (unnamed assert)
|
333 | # wheee
|
334 | ok 4 (unnamed assert)
|
335 |
|
336 | 1..4
|
337 | # tests 4
|
338 | # pass 3
|
339 | # fail 1
|
340 | ```
|
341 |
|
342 | ### object stream reporter
|
343 |
|
344 | Here's how you can render an object stream instead of TAP:
|
345 |
|
346 | ``` js
|
347 | var test = require('tape');
|
348 | var path = require('path');
|
349 |
|
350 | test.createStream({ objectMode: true }).on('data', function (row) {
|
351 | console.log(JSON.stringify(row))
|
352 | });
|
353 |
|
354 | process.argv.slice(2).forEach(function (file) {
|
355 | require(path.resolve(file));
|
356 | });
|
357 | ```
|
358 |
|
359 | The output for this runner is:
|
360 |
|
361 | ```
|
362 | $ node object.js test/x.js test/y.js
|
363 | {"type":"test","name":"(anonymous)","id":0}
|
364 | {"id":0,"ok":false,"name":"should be equal","operator":"equal","actual":"beep","expected":"boop","error":{},"test":0,"type":"assert"}
|
365 | {"type":"end","test":0}
|
366 | {"type":"test","name":"(anonymous)","id":1}
|
367 | {"id":0,"ok":true,"name":"should be equal","operator":"equal","actual":2,"expected":2,"test":1,"type":"assert"}
|
368 | {"id":1,"ok":true,"name":"(unnamed assert)","operator":"ok","actual":true,"expected":true,"test":1,"type":"assert"}
|
369 | {"type":"end","test":1}
|
370 | {"type":"test","name":"wheee","id":2}
|
371 | {"id":0,"ok":true,"name":"(unnamed assert)","operator":"ok","actual":true,"expected":true,"test":2,"type":"assert"}
|
372 | {"type":"end","test":2}
|
373 | ```
|
374 |
|
375 | # install
|
376 |
|
377 | With [npm](https://npmjs.org) do:
|
378 |
|
379 | ```
|
380 | npm install tape --save-dev
|
381 | ```
|
382 |
|
383 | # license
|
384 |
|
385 | MIT
|