A Test-Anything-Protocol library for JavaScript with comprehensive testing capabilities and plugin-based architecture
npx @tessl/cli install tessl/npm-tap@21.1.0TAP is a comprehensive Test-Anything-Protocol testing framework for Node.js, built with TypeScript and providing both ESM and CommonJS support. It combines a command-line test runner with a JavaScript framework for writing test scripts, featuring a powerful plugin system where almost all functionality is implemented as plugins.
npm install tapimport { t } from "tap";
// or
import tap from "tap";For individual imports:
import { test, ok, same, throws } from "tap";CommonJS:
const { t } = require("tap");
// or
const tap = require("tap");import { test } from "tap";
// Basic test with assertions
test("basic math", (t) => {
t.ok(2 + 2 === 4, "addition works");
t.same({ a: 1 }, { a: 1 }, "objects are equal");
t.end();
});
// Async test
test("async operations", async (t) => {
const result = await someAsyncFunction();
t.ok(result.success, "async operation succeeded");
});
// Test with plan
test("planned test", (t) => {
t.plan(2);
t.ok(true, "first assertion");
t.ok(true, "second assertion");
});TAP is built around several key architectural concepts:
The primary interface is the t object, which is a TAP instance providing all testing functionality:
const t: TAP;interface TAP {
// Test organization methods
test(name: string, fn?: TestFunction): Promise<void>;
test(name: string, options: TestOpts, fn?: TestFunction): Promise<void>;
// Basic assertions (using MessageExtra pattern)
ok(value: any, ...[msg, extra]: MessageExtra): boolean;
notOk(value: any, ...[msg, extra]: MessageExtra): boolean;
pass(...[msg, extra]: MessageExtra): boolean;
fail(...[msg, extra]: MessageExtra): boolean;
// Test control
plan(count: number): void;
end(): void;
bailout(reason?: string): void;
timeout(ms: number): void;
}
interface TestOpts {
name?: string;
timeout?: number;
skip?: boolean | string;
todo?: boolean | string;
only?: boolean;
}
type MessageExtra = [] | [msg: string, extra?: Extra] | [extra: Extra];
interface Extra {
[key: string]: any;
compareOptions?: CompareOptions;
}
type TestFunction = (t: TAP) => void | Promise<void>;Comprehensive assertion library with deep equality, pattern matching, type checking, error handling, and promise testing. Includes over 30 assertion methods with TypeScript type guards and flexible parameter patterns.
// Basic assertions (using MessageExtra pattern)
function ok(value: any, ...[msg, extra]: MessageExtra): boolean;
function same(found: any, wanted: any, ...[msg, extra]: MessageExtra): boolean;
function equal<T>(found: any, wanted: T, ...[msg, extra]: MessageExtra): found is T;
function throws(fn: Function | (() => any), ...[wanted, msg, extra]: ThrowsArgs): boolean | Error;
function rejects<T>(fnOrPromise: (() => Promise<T>) | Promise<T>, ...[wanted, msg, extra]: ThrowsArgs): Promise<boolean | Error>;Test creation, skipping, planning, and control flow management for organizing test suites.
function test(name: string, fn?: TestFunction): Promise<void>;
function skip(name: string, fn?: TestFunction): Promise<void>;
function todo(name: string, fn?: TestFunction): Promise<void>;
function plan(count: number): void;Before and after hooks for test setup and teardown at multiple levels.
function before(fn: () => void | Promise<void>): void;
function after(fn: () => void | Promise<void>): void;
function beforeEach(fn: () => void | Promise<void>): void;
function afterEach(fn: () => void | Promise<void>): void;Module mocking, function interception, and call capturing for isolating tests.
function mockRequire(module: string, mocks?: any): void;
function mockImport(module: string, mocks?: any): Promise<void>;
function intercept(object: any, property: string, options?: InterceptOpts): void;Test external processes, worker threads, and stdin/stdout interactions.
function spawn(cmd: string, args?: string[], options?: SpawnOpts, name?: string): Promise<void>;
function worker(file: string, options?: WorkerOpts, name?: string): Promise<void>;
function stdin(input: string, options?: StdinOpts, name?: string): Promise<void>;TAP uses a plugin-based architecture where functionality is modular:
Core Plugins (automatically loaded):
@tapjs/asserts - All assertion methods@tapjs/core - Core TAP functionality and base classes@tapjs/test - Main Test class@tapjs/filter - Test filtering (only method)@tapjs/before / @tapjs/after - Lifecycle hooks@tapjs/mock - Module mocking system@tapjs/intercept - Function/method interception@tapjs/spawn / @tapjs/worker / @tapjs/stdin - Subprocess testing@tapjs/snapshot - Snapshot testing@tapjs/fixture - Test fixture management@tapjs/typescript - TypeScript supportThe plugin system ensures that types are dynamically updated based on loaded plugins, and functionality is conditionally available based on plugin configuration.
TAP includes a command-line test runner:
# Run all tests
tap
# Run specific test files
tap test/*.js
# Run with coverage
tap --coverage
# Watch mode
tap --watch
# TypeScript files
tap test/*.tsThe CLI automatically handles TypeScript compilation, coverage analysis, and TAP output formatting.