Home - uhop/tape-six GitHub Wiki

Dashboard

Node.js CI NPM version

tape-six is a TAP-based library for unit tests. Written in modern JavaScript for modern JavaScript runtimes — works in Node, Deno, Bun, and browsers.

See Examples.

For AI assistants: see llms.txt and llms-full.txt for LLM-optimized documentation.

Major features:

  • Zero runtime dependencies.
  • ES and CommonJS modules are fully supported.
  • Supports Node, Bun and Deno.
  • Supports browsers.
  • TypeScript support:
    • Runs TypeScript code with modern versions of Node, Bun and Deno without transpilation.
    • TS bindings are included.
  • Test files can be run directly.
    • They can be debugged without any transpilation.
      • Your code is not obfuscated by the test harness.
    • You can include console output to trace execution.
  • You control how much information should be shown when tests are run.
    • For example, you can skip output for passing tests, which don't need your attention.
  • You can run tests in parallel to speed up test execution.
  • Before/after hooks (beforeAll, afterAll, beforeEach, afterEach) for set-up and tear-down.
  • signal property on the tester for cancelling pending async operations on timeout or bail-out.
  • Bring-your-own assertion / mocking / property-based libraries — node:assert, chai, expect, node:test mock, sinon, fast-check. See 3rd-party libraries.
  • Plugins extend the tester with custom methods via registerTesterMethod. See Writing plugins.

It uses a familiar API for unit testing and supports browser-based and command-line testing, debugging and visualizing results.

How to use

  1. Install tape-six in your project: npm i -D tape-six.
  2. Write tests (see below).
  3. Configure your tests: set-up tests.
  4. Run tests: npm test (see tape6).

Example:

import test from 'tape-six';
// CommonJS:
// const {test} = require('tape-six');

test('Sample test', t => {
  t.ok(1 < 2, '1 is less than 2');
  t.deepEqual([1], [1], '[1] is equal to [1]');
});

The same example using chai assertions:

import test from 'tape-six';
import {assert, expect} from 'chai';

test('Sample test', t => {
  // two different styles
  expect(1).to.be.lessThan(2);
  assert.deepEqual([1], [1], '[1] is equal to [1]');
});

See 3rd-party assertion libraries for more, plus mock libraries and property-based testing.

To help port tests from other frameworks, test() is aliased as suite(), describe() and it(). When called inside a test body, these functions automatically delegate to the current tester (see test() for details). Using t.test() directly is still preferred because it makes the delegation explicit.

Writing tests

To register a function as a test, use the test() function. That function is called with a tester object as the first argument. See Tester for details. The test function can be synchronous or asynchronous.

If your tests require callbacks (streams, events, callback-based APIs), you can use test.asPromise() helper. A test function is called with three arguments: a tester object, resolve() and reject() functions.

tape-six supports set-up and tear-down hooks that run regardless of test outcome. Like test() and its aliases, the top-level hook functions (beforeAll, afterAll, beforeEach, afterEach, and their before/after aliases) auto-delegate to the current tester when called inside a test body. Using t.beforeAll(), etc. is preferred. Read all about it in before and after hooks.

The test files are directly runnable.

If for some reason you want to split your tests into multiple files, yet run them as one file, it is possible: just import other test files into some "main" file. It will still be directly runnable.

When you run test files directly all tests in them run sequentially. Obviously it doesn't scale well if you have a lot of tests (you should!). In this case tape6 utility helps run tests in parallel.

Configuring your project

TL;DR version — add to your package.json:

{
  // ...
  "scripts": {
    "test": "tape6 --flags FO",
    "start": "tape6-server --trace"
  }
  // ...
  "tape6": {
    "tests": ["/tests/test-*.*js"],
    "importmap": {
      "imports": {
        "tape-six": "/node_modules/tape-six/index.js",
        "tape-six/": "/node_modules/tape-six/src/",
        "my-package": "/index.js",
        "my-package/": "/src/"
      }
    }
  }
}

(You want to add tape6-server only if you plan to run browser-based tests).

For more details, see set-up tests.

Available utilities

Test files are directly executable with Node, Bun, Deno or in a browser. Yet for a superior developer experience, a number of utilities are available:

  • tape6 for running tests.
    • tape6-node for running tests in Node.js.
    • tape6-bun for running tests in Bun.
    • tape6-deno for running tests in Deno.
    • Otherwise tape6 will detect the environment and use the appropriate runner.
    • tape6-seq for running tests in sequence without spinning off threads.
  • tape6-server for serving files and running tests in a web server.
  • tape6-runner for helping writing custom shell scripts.

Subpath modules for HTTP testing

  • tape-six/server — ephemeral HTTP server harness (withServer, startServer, setupServer).
  • tape-six/response — response reading helpers (asText, asJson, asBytes, header, headers).

Test output can be controlled by flags. See Supported flags for details.

Check out the sister projects:

Notes on various environments

tape-six is used in different environments:

Formalities

The project is distributed under the 3-clause BSD license.

Other pertinent information:

⚠️ **GitHub.com Fallback** ⚠️