Testing Your Code

Junior Year, page 8 of 11. A one-minute read.

How do you know your code works? So far, you've been running it and eyeballing the output. That's fine for small programs, but in big projects, a change in one place can quietly break something somewhere else. Professional developers write automated tests: little programs that check their code gives the right answers.

Node has a test runner built in. Let's test the math-utils.js module from the start of this year. Create math-utils.test.js:

math-utils.test.js
import { test } from "node:test";
import assert from "node:assert/strict";
import { add, circleArea } from "./math-utils.js";

test("add puts two numbers together", () => {
  assert.equal(add(2, 3), 5);
  assert.equal(add(-1, 1), 0);
});

test("circleArea of radius 1 is PI", () => {
  assert.equal(circleArea(1), 3.14159);
});

test("this test will fail on purpose", () => {
  assert.equal(add(0.1, 0.2), 0.3);
});

Run the tests with:

Terminal
node --test

Node finds every file ending in .test.js and runs it. You'll see a ✔ next to each passing test and a ✖ next to the failure, with a message explaining what went wrong: it expected 0.3 but got 0.30000000000000004. (Our old friend floating point, from Grade 2!)

assert.equal(actual, expected) checks that two values are equal, and makes the test fail if they're not. There's also assert.deepEqual for comparing arrays and objects by their contents, and assert.throws for checking that something throws an error.

Once you have tests, you can change your code with confidence: just run node --test again, and if everything's still green, you didn't break anything.

Reading is step one

CurlyScript turns these notes into a game: short questions, an explanation after every answer, and a test at the end of each grade. Free, with nothing to sign up for.

Start learning