Node Test Runner
On this page
Why the Built-in Runner Matters
Node's native test runner provides a stable baseline without pulling in a full framework. In production-focused codebases, fewer dependencies often means fewer supply-chain risks and fewer breaking upgrades.
Core Concepts
test()defines a test casedescribe()groups related testsbefore(),beforeEach(),after(),afterEach()manage lifecycleassertprovides standard assertions
Minimal Example
import test from 'node:test';
import assert from 'node:assert/strict';
test('adds numbers', () => {
assert.equal(2 + 3, 5);
});
Async Tests
Async tests should return a promise (or use async). Avoid manual done-callback patterns unless required for legacy APIs.
import test from 'node:test';
import assert from 'node:assert/strict';
test('async behavior', async () => {
const value = await Promise.resolve(42);
assert.equal(value, 42);
});
TypeScript-First Usage
In TypeScript projects, compile tests as part of CI or run them via a TS execution layer. The production goal is determinism: test execution must match the runtime assumptions of your deployed build.
Where It Fits
Use the built-in runner for fast unit tests and many integration tests. If you need advanced features (snapshot UI, complex mocking ecosystem, browser automation), layer additional tooling intentionally.