IntermediateTypeScript · Lesson 7 of 9

Testing with node:test

Write automated tests with Node's built-in test runner and assertions.

Automated tests check that your code does what you expect — and keep checking every time you change it. Node.js includes a test runner (node:test) and assertions (node:assert/strict), so you don't need extra libraries to start.

Group related tests with describe, write each case with it (or test), and cover the normal case, edge cases (empty input, zero, boundaries) and error cases.

Pure functions — same input, same output, no side effects — are the easiest to test, which is one more reason to keep business logic separate from I/O.

grade.tsTypeScript
export function gradeFor(score: number): string {
  if (!Number.isFinite(score) || score < 0 || score > 100) {
    throw new RangeError("Score must be between 0 and 100");
  }
  if (score >= 75) return "A";
  if (score >= 65) return "B";
  if (score >= 45) return "C";
  if (score >= 30) return "D";
  return "F";
}
grade.test.tsTypeScript
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { gradeFor } from "./grade";

describe("gradeFor", () => {
  it("returns A for top scores", () => {
    assert.equal(gradeFor(90), "A");
  });

  it("handles grade boundaries exactly", () => {
    assert.equal(gradeFor(75), "A");
    assert.equal(gradeFor(74), "B");
    assert.equal(gradeFor(30), "D");
    assert.equal(gradeFor(29), "F");
  });

  it("rejects out-of-range scores", () => {
    assert.throws(() => gradeFor(101), RangeError);
    assert.throws(() => gradeFor(-1), RangeError);
  });
});
TerminalShell
node --import tsx --test grade.test.ts

Key points

  • Test behaviour, including boundaries and failure cases — not just the happy path.
  • node:test + node:assert/strict need no extra dependencies.
  • Keep logic in pure functions so it's easy to test.

Exercise

Write tests for the parseAge function from the Error Handling lesson: a valid age, a decimal, a negative number, text input and the boundaries 0 and 120. Add a test script to package.json.

Show solution

Try the exercise yourself first — then compare your approach with this one.

Test the normal case, each failure reason, and both boundaries (0 and 120). Each test checks the whole Result with assert.deepEqual, so a wrong error message is caught too.

parse-age.tsTypeScript
export type Result<T> = { ok: true; value: T } | { ok: false; error: string };

export function parseAge(input: string): Result<number> {
  const n = Number(input);
  if (!Number.isInteger(n)) return { ok: false, error: "Age must be a whole number" };
  if (n < 0 || n > 120) return { ok: false, error: "Age must be between 0 and 120" };
  return { ok: true, value: n };
}
parse-age.test.tsTypeScript
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { parseAge } from "./parse-age";

describe("parseAge", () => {
  it("accepts a valid age", () => {
    assert.deepEqual(parseAge("17"), { ok: true, value: 17 });
  });

  it("accepts the boundaries 0 and 120", () => {
    assert.deepEqual(parseAge("0"), { ok: true, value: 0 });
    assert.deepEqual(parseAge("120"), { ok: true, value: 120 });
  });

  it("rejects decimals and text", () => {
    assert.deepEqual(parseAge("17.5"), { ok: false, error: "Age must be a whole number" });
    assert.deepEqual(parseAge("abc"), { ok: false, error: "Age must be a whole number" });
  });

  it("rejects ages out of range", () => {
    assert.deepEqual(parseAge("-1"), { ok: false, error: "Age must be between 0 and 120" });
    assert.deepEqual(parseAge("121"), { ok: false, error: "Age must be between 0 and 120" });
  });
});
package.jsonJSON
{
  "scripts": {
    "test": "node --import tsx --test *.test.ts"
  }
}

Check your understanding

  1. Which modules provide a test runner and assertions built into Node.js?

  2. For gradeFor with an A at 75 and above, which pair of values best tests the boundary?

  3. How do you check that a function throws a RangeError?

  4. Why are pure functions the easiest to test?

Ask AI