Search across all documentation pages
10 examples to get you started with Testing - 7 basic and 3 intermediate.
node:test and node:assert.createApp() export pattern.npm install -D tsx supertest @types/supertest for HTTP integration tests.Balance fast unit tests with fewer integration and E2E tests.
/ E2E \ few - critical user journeys
/ contract \ consumer-provider agreements
/ integration \ HTTP + DB with Testcontainers
/ unit tests \ many - pure logic, handlers mocked
Zero-dependency test runner built into Node 24.
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { calculateTax } from "../src/billing/tax.js";
describe("calculateTax", () => {
it("applies rate to subtotal", () => {
assert.equal(calculateTax(100, 0.2), 20);
});
});node --import tsx --test test/tax.test.tsnode:assert/strict uses === semantics.Related: node:test & node:assert - full runner guide
Separate server factory from listen for Supertest.
// src/app.ts
import express from "express";
export function createApp() {
const app = express();
app.get("/health", (_req, res) => res.json({ ok: true }));
createApp() without binding a port.server.ts calls createApp().listen(...).app.ready().Related: Supertest & HTTP Integration - in-process HTTP
Readable tests document expected behavior.
it("returns 404 for unknown invoice", async () => {
// Arrange
const app = createApp();
// Act
const res = await request(app).get("/invoices/missing");
// Assert
assert.equal(res.status,
returns 404 when ....Reset mocks and state between cases.
import { beforeEach, describe, it } from "node:test";
let cache: Map<string, string>;
beforeEach(() => {
cache = new Map();
});Single entry for local and CI.
{
"scripts": {
"test": "node --import tsx --test",
"test:unit": "node --import tsx --test test/unit",
"test:integration": "node --import tsx --test test/integration"
}
}Use .env.test or inline defaults for test-only config.
process.env.DATABASE_URL ??= "postgres://localhost:5432/billing_test";
process.env.LOG_LEVEL = "silent";LOG_LEVEL=silent keeps test output readable.Testcontainers spins ephemeral DB in CI.
// test/integration/invoices.test.ts - conceptual placement
// See Testcontainers page for full setupRelated: Testcontainers - Postgres/Redis in CI
Consumer defines expected provider response shape.
// Consumer pact test - provider must match published contract
// See Contract & Pact pageRelated: Contract & Pact Tests - microservice boundaries
Baseline latency and error rate under expected RPS.
k6 run scripts/load/smoke.jsRelated: Load Testing with k6/Artillery - baseline RPS
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.