Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

node:test

ImportsImplementation
node:test, node:test/reporters@bytecodealliance/jco-std/wasi/0.2.x/node/24.x.x/test and /test/reporters

node:test and node:test/reporters target Node.js 24.20.0. Application code keeps its ordinary imports:

import test from "node:test";
import assert from "node:assert/strict";

await test("addition", async (t) => {
  t.plan(2);
  t.assert.strictEqual(2 + 3, 5);
  await t.test("nested", () => {
    assert.deepStrictEqual([1, 2], [1, 2]);
  });
});

export function run() { return "tests completed"; }

Bundle against a world exporting run: func() -> string with jco componentize app.js --bundle --wit wit -o app.wasm. Top-level tests run when the engine evaluates the module, which may happen during component initialization at build time. Tests return promises that resolve even on failure, as in Node. Failures appear in TAP output; t.passed and t.error are available in cleanup hooks for applications that need to expose a result through WIT. The runner does not set the host process’s exit code. A returned “tests completed” string alone is not evidence that assertions passed.

Tests execute serially. Synchronous, promise and callback test bodies, nested tests, synchronous suite declarations, describe/it aliases, hooks, skip/TODO/expected-failure directives, assertion plans, tags, and waitFor are supported. only/runOnly emit Node’s diagnostic outside test-only mode; Jco has no Node test-runner CLI mode. Global teardown runs when the registered queue drains, so suites are the preferred scope for setup and teardown across related tests.

Reuse and engine requirements

The test adapter reuses jco-std’s assertion implementation, error codes, inspection, path implementation, stream transforms, promise detection, Abort compatibility, and signal validation. Assertion behavior and error identities therefore agree with node:assert in the same bundle. Function, method, getter, setter and property mocks retain the portable proxy and restoration algorithms from Node. There are no new dependencies. The port records provenance against Node commit 71b8b174857e25106d39b61a9e6f30d927da8b01 and retains its MIT notice.

The runner requires engine AbortController; StarlingMonkey provides it. The pinned QuickJS backend does not, so starting a test or suite throws ERR_JCO_UNSUPPORTED_NODE_API. Importing the module, standalone mocking and reporting still work there. Timeouts, delayed plans and waitFor additionally use the engine’s timer functions.

getTestContext() tracks synchronous callbacks. Component engines cannot propagate implicit test context through await; use the explicit t.test() and t hook methods after asynchronous boundaries. A global test/hook registration while an async body is pending throws with that guidance. Async suite declarations and concurrency: true or numbers greater than one are unsupported. File paths and worker IDs are undefined; attempts are zero. The adapter does not intercept unhandled rejections, uncaught exceptions, process signals, or test tracing events.

Mocks, snapshots and reporters

Each test owns a mock tracker that resets after cleanup hooks. Standalone mock has explicit reset and restoreAll methods. Mock calls retain arguments, receivers, results, errors and constructor targets. Property mocks retain access history and one-use replacements. Symbol methods restore correctly, fixing the pinned upstream implementation’s string-only restoration check.

run() (file discovery, watch mode, isolation and coverage), module loader mocks, native timer mocking, and snapshot APIs throw ERR_JCO_UNSUPPORTED_NODE_API without invoking supplied callbacks or reading their options. The deprecated array form of mock.timers.enable() throws ERR_JCO_UNSUPPORTED_DEPRECATED_NODE_API. These APIs cannot be implemented by passing guest closures through a host capability.

dot, tap and junit consume event iterables. spec and lcov are callable and constructible jco-std stream transforms. Reports use no ANSI colors or host terminal discovery; dot wraps at 20 columns and JUnit leaves hostname empty. TAP error details and human-readable coverage tables use portable formatting and omit engine stack frames. LCOV can format supplied coverage events even though the component runner cannot collect V8 coverage. Importing reporters requires no filesystem or process provider.