Testing foundations
Run the first Node test
Use the built-in Node.js test runner and strict assertions to execute one fast deterministic test without another framework.
8 minute lesson
Modern Node.js includes a stable test runner. It discovers tests, reports failures, supports filtering, mocking, and coverage, and works with ordinary modules.
Keep tests beside a small module or under a predictable tests directory. Use strict assertions so coercion cannot turn the wrong type into an apparent pass.
import test from 'node:test'
import assert from 'node:assert/strict'
import { normalizeTitle } from './books.js'
test('normalizes surrounding whitespace', () => {
assert.equal(normalizeTitle(' Dune '), 'Dune')
})
The test name should describe the behavior, not the function name. When this fails, Node reports the test, expected value, actual value, and stack location. That evidence is part of the design: normalizes title is less useful than removes surrounding whitespace but preserves internal spaces.
Make sure the assertion observes the returned value. This test would be a false positive if it asserted the input string or a constant that the function never produced. A useful habit is to mutate the implementation briefly—return the original string—and confirm that the test turns red for the expected reason. Then restore the implementation and watch it pass again. This red-green check proves that the test is connected to the behavior.
Add a second case for 'The Left Hand of Darkness'. Decide whether two internal spaces are preserved or collapsed, encode that decision in the name and expectation, then run node --test. Deliberately make one expectation wrong and use the diagnostic to locate the mismatch before correcting it.
Lesson completed