Project tests catch small regressions before a Node.js change reaches a package script, pull request, or deployment. The built-in node:test runner keeps that check inside Node.js itself when a separate framework is unnecessary.
Using ES module files with the .mjs extension avoids a package metadata prerequisite, so the first test can run before package.json has a module type. node:assert/strict raises assertion errors for mismatched values, and node –test reports those failures through the test runner.
Test file names control discovery. node –test finds names such as *.test.mjs and files under test/, so the test file should follow those patterns or be passed explicitly to the runner.
export function add(left, right) { return left + right; }
import test from "node:test"; import assert from "node:assert/strict"; import { add } from "../lib/math.mjs"; test("adds two numbers", () => { assert.strictEqual(add(2, 3), 5); });
The .test.mjs suffix lets node –test discover the file without extra arguments. Use .test.js instead when the project is already configured for ES modules.
Related: How to enable ES modules in Node.js
$ node --test ✔ adds two numbers (0.574709ms) ℹ tests 1 ℹ suites 0 ℹ pass 1 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 54.636666
Keep this as a deliberate failure check only. A failing test exits with a nonzero status and should not remain in the committed test file.
$ node --test
✖ adds two numbers (1.194625ms)
ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 60.495
✖ failing tests:
test at test/math.test.mjs:5:1
✖ adds two numbers (1.194625ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
5 !== 6
##### snipped #####
{
code: 'ERR_ASSERTION',
actual: 5,
expected: 6,
operator: 'strictEqual',
diff: 'simple'
}
$ node --test ✔ adds two numbers (0.829292ms) ℹ tests 1 ℹ suites 0 ℹ pass 1 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 65.937