UNPKG

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