Course progress0%
Course content

Module 1

Module 2

Module 3

Module 4

Module 5

Module 6

Module 7

Module 8

Module 9

Module 10

Module 11

Module 12

Module 13

Module 14

Module 15

Module 16

Module 17

Module 18

40 min

Testing Boundaries and Refactoring Safely

Build a compact test matrix

By the end of this lesson

  • Build a compact test matrix
  • Protect behavior during a structural change

Cover different reasons to fail

A grade average accepts numeric grades from 0 through 20, returns null for an empty array and rejects invalid inputs. Separate normal, boundary, absent and malformed cases rather than listing many near-identical examples.

Case Expected behavior
[12, 16] 14
[0, 20] 10
[] null
["12"] Error
[-1] Error
null Error

Use the validated calculateAverage function from the defensive programming module. In your test file import it from calculations.mjs along with Node's strict assert module.

import assert from "node:assert/strict";
import { calculateAverage } from "./calculations.mjs";
assert.equal(calculateAverage([12, 16]), 14);
assert.equal(calculateAverage([0, 20]), 10);
assert.equal(calculateAverage([]), null);
assert.throws(() => calculateAverage(["12"]));
assert.throws(() => calculateAverage([-1]));
assert.throws(() => calculateAverage(null));

Guided refactor

Replace a reduce-based sum with a for...of loop, preserving validation and empty-input behavior. Rerun the same cases. Passing tests provide evidence that these behaviors survived; inspect the change too, because the suite may not cover everything.

For decimal results, use an appropriate tolerance or a domain rounding policy rather than assuming every floating-point fraction has exact binary representation. Integer-cent money calculations still need explicit rounding when applying rates.

Independent exercise

Add a case that verifies the average function does not mutate the supplied array. Then extend the policy to allow a grade of 20.5. Which expectations must be reviewed?

Correction

Keep a copy of the input, call the function, then deep-compare the original with the copy. A new upper bound changes the validation contract: add 20.5 as accepted and a value just above it as rejected. Do not change the implementation alone while leaving the old policy in the lesson or tests.

Review

A useful regression suite records important decisions. When a rule changes, update requirements, examples and implementation together, and preserve tests for unaffected behavior.

Lesson complete?

Your progress is saved on this device.