https://github.com/tapjs/node-test-example
https://github.com/tapjs/node-test-example
Last synced: 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/tapjs/node-test-example
- Owner: tapjs
- Created: 2023-09-15T18:09:50.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-10-03T17:31:12.000Z (over 1 year ago)
- Last Synced: 2025-03-27T23:07:01.719Z (3 months ago)
- Language: JavaScript
- Size: 52.7 KB
- Stars: 4
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# node-test-example
An example showing `node:test`, `node --test`, `import 'tap'` and
`tap run` being used together, and how they interoperate.This contains a `test/tap.test.js` and `test/node.test.js`, which
both run essentially the same tests, one using
[`tap`](https://node-tap.org) and the other using
[`node:test`](https://nodejs.org/api/test.html)## The tests fail!
I know. That's kinda the point.
* `npm run test:node` Executes both test suite files with the
`node --test` runner.
* `npm run test:tap` Execute both test suite files with the
`tap` runner.In both cases, you can see that the results are pretty similar.
## Differences
- When running with the `tap` runner, they're almost identical.
The main thing is that the `node:test` doesn't provide
per-assertion reporting, so you only see a report on the test
block, and possibly the first failure, not all the assertions
within it.
- When running with the `node --test` runner, the `tap` test
provides diffs and source callsite printing, while the
`node:test` test shows a `console.log()` of the thrown Error.Of course, the two runners produce very different output overall,
but they should both be pretty sensible.Personally, I think the tap runner is a lot more useful, and
certainly if you write tests in TypeScript (or use tap's `import`
mocking) it's nice to not have to specify the `--loader` and
`--import` arguments explicitly.But on the flip side, that fanciness comes with a cost. With
TypeScript disabled, `tap` runs these two tests in about 450ms on
my system (350ms or so with coverage disabled), while `node
--test` does it in around 170ms. In both cases, the
`test/tap.test.js` test takes around 150ms to run, and the
`test/node.test.js` takes under 10ms.Real world tests doing complicated stuff would show a less
dramatic difference, so this is in no way a representative
benchmark, but as always, performance and features are
fundamentally opposed, because features require running code, and
not running code is always faster.The goal of the `node:test` interoperability in node-tap is to
make it possible for you to get the best of both worlds. You
could have part of your test suite written as `node:test` tests,
if they don't need `t.mockImport` or TypeScript, and other tests
written in `tap`.## Coverage
The `test:mix` and `test:cross` show using the `node --test` and
`tap` runners so that they dump coverage into the same folder.
Then you can use `tap report` to report on it.## Enough talk! Show the output!
GitHub strips colors from README.md files. [A more representative
example with colors can be found on the node-tap
website.](https://node-tap.org/node-test-interop/#enough-talk!-show-the-output!)Running with `tap`:
FAIL test/node.test.js 2 failed of 4 6.834ms
✖ suite of tests that fail > uhoh, this one throws
✖ suite of tests that fail > failer
FAIL test/tap.test.js 3 failed of 18 340ms
✖ suite of tests that fail > uhoh, this one throws > Invalid time value lib/index.mjs:11:43
✖ suite of tests that fail > failer > should be equal test/tap.test.js:35:7
✖ suite of tests that fail > failer > should be equal test/tap.test.js:37:7
🌈 TEST COMPLETE 🌈
FAIL test/node.test.js 2 failed of 4 6.834ms
✖ suite of tests that fail > uhoh, this one throws
test/node.test.js
20 })
21
22 test('suite of tests that fail', async t => {
23 await t.test('uhoh, this one throws', () => {
━━━━━━━━━━━━━┛
24 assert.equal(thrower(0), '1970-01-01T00:00:00.000Z')
25 assert.equal(thrower(1234567891011), '2009-02-13T23:31:31.011Z')
26 assert.equal(thrower({}), 'Invalid Date')
27 })
error origin: lib/index.mjs
8
9 // This is a function that throws, to show how both
10 // handle errors.
11 export const thrower = (n) => new Date(n).toISOString()
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13 // one that fails, to show how failures are handled
14 export const failer = (n) => String(n + 1)
error: Invalid time value
code: ERR_TEST_FAILURE
failureType: testCodeFailure
name: RangeError
Date.toISOString (<anonymous>)
thrower (lib/index.mjs:11:43)
TestContext.<anonymous> (test/node.test.js:26:18)
TestContext.<anonymous> (test/node.test.js:23:11)✖ suite of tests that fail > failer
test/node.test.js
26 assert.equal(thrower({}), 'Invalid Date')
27 })
28
29 await t.test('failer', () => {
━━━━━━━━━━━━━┛
30 assert.equal(failer(1), '2')
31 assert.equal(failer(-1), '0')
32 // expect to convert string numbers to Number, but doesn't
33 assert.equal(failer('1'), '2')
error origin: test/node.test.js
30 assert.equal(failer(1), '2')
31 assert.equal(failer(-1), '0')
32 // expect to convert string numbers to Number, but doesn't
33 assert.equal(failer('1'), '2')
━━━━━━━━━━━━━━┛
34 // expect to convert non-numerics to 0, but it doesn't
35 assert.equal(failer({}), '1')
36 })
37 })
--- expected
+++ actual
@@ -1,1 +1,1 @@
-"2"
+"11"
error: "'11' == '2'"
code: ERR_ASSERTION
failureType: testCodeFailure
name: AssertionError
operator: ==
TestContext.<anonymous> (test/node.test.js:33:12)
TestContext.<anonymous> (test/node.test.js:29:11)FAIL test/tap.test.js 3 failed of 18 340ms
✖ suite of tests that fail > uhoh, this one throws > Invalid time value
lib/index.mjs
8
9 // This is a function that throws, to show how both
10 // handle errors.
11 export const thrower = (n) => new Date(n).toISOString()
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13 // one that fails, to show how failures are handled
14 export const failer = (n) => String(n + 1)
type: RangeError
tapCaught: testFunctionThrow
Date.toISOString (<anonymous>)
thrower (lib/index.mjs:11:43)
Test.<anonymous> (test/tap.test.js:27:13)✖ suite of tests that fail > failer > should be equal
test/tap.test.js
32 t.equal(failer(1), '2')
33 t.equal(failer(-1), '0')
34 // expect to convert string numbers to Number, but doesn't
35 t.equal(failer('1'), '2')
━━━━━━━━━┛
36 // expect to convert non-numerics to 0, but it doesn't
37 t.equal(failer({}), '1')
38 t.end()
39 })
--- expected
+++ actual
@@ -1,1 +1,1 @@
-2
+11
compare: ===
Test.<anonymous> (test/tap.test.js:35:7)
Test.<anonymous> (test/tap.test.js:31:5)
test/tap.test.js:23:3✖ suite of tests that fail > failer > should be equal
test/tap.test.js
34 // expect to convert string numbers to Number, but doesn't
35 t.equal(failer('1'), '2')
36 // expect to convert non-numerics to 0, but it doesn't
37 t.equal(failer({}), '1')
━━━━━━━━━┛
38 t.end()
39 })
40
41 t.end()
--- expected
+++ actual
@@ -1,1 +1,1 @@
-1
+[object Object]1
compare: ===
Test.<anonymous> (test/tap.test.js:37:7)
Test.<anonymous> (test/tap.test.js:31:5)
test/tap.test.js:23:3Asserts: 17 pass 5 fail 22 of 22 complete
Suites: 0 pass 2 fail 2 of 2 complete# { total: 22, pass: 17, fail: 5 }
# time=459.924msRunning with `node --test`:
✔ add (0.569917ms)
✔ stringOrNull (0.063833ms)
▶ suite of tests that fail
✖ uhoh, this one throws (0.910959ms)
RangeError [Error]: Invalid time value
at Date.toISOString (<anonymous>)
at thrower (file:///Users/isaacs/dev/tapjs/node-test-example/lib/index.mjs:11:43)
at TestContext.<anonymous> (file:///Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:26:18)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:631:25)
at Test.start (node:internal/test_runner/test:542:17)
at TestContext.test (node:internal/test_runner/test:167:20)
at TestContext.<anonymous> (file:///Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:23:11)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:631:25)✖ failer (0.532708ms)
AssertionError [ERR_ASSERTION]: '11' == '2'
at TestContext.<anonymous> (file:///Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:33:12)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:631:25)
at Test.start (node:internal/test_runner/test:542:17)
at TestContext.test (node:internal/test_runner/test:167:20)
at TestContext.<anonymous> (file:///Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:29:11)
at async Test.run (node:internal/test_runner/test:632:9)
at async Test.processPendingSubtests (node:internal/test_runner/test:374:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '11',
expected: '2',
operator: '=='
}▶ suite of tests that fail (1.684292ms)
✔ add (1.774ms)
✔ stringOrNull (1.091ms)
▶ suite of tests that fail
✖ uhoh, this one throws (10.016ms)
Error: Invalid time value
| // This is a function that throws, to show how both
| // handle errors.
| export const thrower = (n) => new Date(n).toISOString()
| ------------------------------------------^
|
| // one that fails, to show how failures are handled
at Date.toISOString (<anonymous>)
at thrower (/Users/isaacs/dev/tapjs/node-test-example/lib/index.mjs:11:43)
at Test.<anonymous> (/Users/isaacs/dev/tapjs/node-test-example/test/tap.test.js:27:13) {
type: 'RangeError',
tapCaught: 'testFunctionThrow'
}✖ failer (3.676ms)
Error: should be equal
--- expected
+++ actual
@@ -1,1 +1,1 @@
-2
+11
| t.equal(failer(-1), '0')
| // expect to convert string numbers to Number, but doesn't
| t.equal(failer('1'), '2')
| ------^
| // expect to convert non-numerics to 0, but it doesn't
| t.equal(failer({}), '1')
at Test.<anonymous> (/Users/isaacs/dev/tapjs/node-test-example/test/tap.test.js:35:7)
at Test.<anonymous> (/Users/isaacs/dev/tapjs/node-test-example/test/tap.test.js:31:5)
at /Users/isaacs/dev/tapjs/node-test-example/test/tap.test.js:23:3 {
compare: '==='
}▶ suite of tests that fail (17.681ms)
ℹ tests 9
ℹ suites 1
ℹ pass 4
ℹ fail 5
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 160.809375✖ failing tests:
test at file:/Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:23:11
✖ uhoh, this one throws (0.910959ms)
RangeError [Error]: Invalid time value
at Date.toISOString (<anonymous>)
at thrower (file:///Users/isaacs/dev/tapjs/node-test-example/lib/index.mjs:11:43)
at TestContext.<anonymous> (file:///Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:26:18)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:631:25)
at Test.start (node:internal/test_runner/test:542:17)
at TestContext.test (node:internal/test_runner/test:167:20)
at TestContext.<anonymous> (file:///Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:23:11)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:631:25)test at file:/Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:29:11
✖ failer (0.532708ms)
AssertionError [ERR_ASSERTION]: '11' == '2'
at TestContext.<anonymous> (file:///Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:33:12)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:631:25)
at Test.start (node:internal/test_runner/test:542:17)
at TestContext.test (node:internal/test_runner/test:167:20)
at TestContext.<anonymous> (file:///Users/isaacs/dev/tapjs/node-test-example/test/node.test.js:29:11)
at async Test.run (node:internal/test_runner/test:632:9)
at async Test.processPendingSubtests (node:internal/test_runner/test:374:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '11',
expected: '2',
operator: '=='
}test at test/tap.test.js:24:5
✖ uhoh, this one throws (10.016ms)
Error: Invalid time value
| // This is a function that throws, to show how both
| // handle errors.
| export const thrower = (n) => new Date(n).toISOString()
| ------------------------------------------^
|
| // one that fails, to show how failures are handled
at Date.toISOString (<anonymous>)
at thrower (/Users/isaacs/dev/tapjs/node-test-example/lib/index.mjs:11:43)
at Test.<anonymous> (/Users/isaacs/dev/tapjs/node-test-example/test/tap.test.js:27:13) {
type: 'RangeError',
tapCaught: 'testFunctionThrow'
}test at test/tap.test.js:31:5
✖ failer (3.676ms)
Error: should be equal
--- expected
+++ actual
@@ -1,1 +1,1 @@
-2
+11
| t.equal(failer(-1), '0')
| // expect to convert string numbers to Number, but doesn't
| t.equal(failer('1'), '2')
| ------^
| // expect to convert non-numerics to 0, but it doesn't
| t.equal(failer({}), '1')
at Test.<anonymous> (/Users/isaacs/dev/tapjs/node-test-example/test/tap.test.js:35:7)
at Test.<anonymous> (/Users/isaacs/dev/tapjs/node-test-example/test/tap.test.js:31:5)
at /Users/isaacs/dev/tapjs/node-test-example/test/tap.test.js:23:3 {
compare: '==='
}