Why Test? First Tests with node:assert

First lesson of the Automated Testing course, free to read: about 15 minutes, 3 exercises and 3 quiz questions. This is the catalogue's base lesson; in the student space, it is rewritten for your profile.

Objectives

  • Explain what an automated test brings and place the levels of the test pyramid
  • Write assertions with node:assert (strictEqual, deepStrictEqual, throws)
  • Choose relevant test cases, including edge cases

AssertionsTest pyramidEdge cases

You fix a VAT calculation, everything seems to work… and three weeks later, someone discovers that discounts no longer apply. An automated test is a small program that runs your code and checks that it produces the expected result. Run on every change, it detects these regressions within seconds.

Tests also bring:

  • confidence to refactor: you can reorganize the code without fear;
  • living documentation: tests show how to use a function;
  • better design: code that is hard to test is often too tightly coupled.

The test pyramid

Level What is tested Speed Quantity
Unit A function or an isolated module Milliseconds Many
Integration Several modules together (route + database) Seconds Medium
End-to-end (E2E) The whole application through the browser Slow Few

We start with the base: unit tests.

Assertions with node:assert

Node.js provides the node:assert module. An assertion checks a condition and throws an AssertionError if it is false.

const assert = require("node:assert");

function prixTTC(ht, taux = 0.2) {
  if (ht < 0) throw new RangeError("Negative price");
  return Math.round(ht * (1 + taux) * 100) / 100;
}

// Simple values: strict comparison (===)
assert.strictEqual(prixTTC(10), 12);
assert.strictEqual(prixTTC(10, 0.055), 10.55);

// Objects and arrays: content comparison
assert.deepStrictEqual([1, 2].map((x) => x * 2), [2, 4]);

// Errors: pass a FUNCTION that assert will call
assert.throws(() => prixTTC(-1), RangeError);

// Regular expressions
assert.match("Order #123", /#\d+/);

Watch out for two pitfalls:

  • assert.equal (non-strict) uses ==: assert.equal(1, "1") passes. Prefer the strict variants, or import require("node:assert/strict").
  • assert.strictEqual({a: 1}, {a: 1}) fails: two distinct objects are not ===. Use deepStrictEqual.

Choosing your test cases

For each function, ask yourself these questions:

  1. Nominal case: does normal use give the right result?
  2. Edge cases: zero, empty string, empty array, a single element, maximum values, rounding.
  3. Invalid inputs: wrong type, negative value, undefined.

A clear error message helps enormously when a test fails:

assert.strictEqual(prixTTC(0), 0, "A zero price must stay zero");

Key takeaways

A test = prepare data, call the code, check the result. Use strict assertions, test edge cases, and keep tests fast and independent.

Exercises

Solutions and tests stay on the server. In the student space, your code is run and checked, and the tutor gives hints before the solution.

  1. CodeDifficulty 1JavaScript in the browser1 hint

    First assertions

    The function moyenne(notes) is provided. Write the function testerMoyenne() that uses assert to check:

    • moyenne([10, 20]) is 15;
    • moyenne([7]) is 7;
    • moyenne([]) throws a RangeError.

    Then call testerMoyenne() at the end of the file.

    function moyenne(notes) {
      if (notes.length === 0) throw new RangeError("Liste vide");
      return notes.reduce((a, b) => a + b, 0) / notes.length;
    }
    
    function testerMoyenne() {
      // Vos assertions ici
    }
    
    testerMoyenne();
  2. CodeDifficulty 2JavaScript in the browser2 hints

    A checker that catches bugs

    Write verifierSlugify(slugify) that receives an implementation of slugify and throws an AssertionError if it is incorrect. A correct implementation must:

    • turn "Bonjour le Monde" into "bonjour-le-monde";
    • trim leading/trailing spaces: " Café " gives "cafe" (accents removed);
    • return "" for an empty string.

    The validator will pass good and bad implementations to your function.

    function verifierSlugify(slugify) {
      // Vos assertions sur slugify(...)
    }
  3. Multiple choiceDifficulty 11 hint

    Choose the right assertion

    Which assertion checks that getUser() returns the object { id: 1, nom: "Ada" }?

    • assert.strictEqual(getUser(), { id: 1, nom: "Ada" })
    • assert.deepStrictEqual(getUser(), { id: 1, nom: "Ada" })
    • assert.ok(getUser() == { id: 1, nom: "Ada" })

End-of-lesson quiz

  1. Which test level should be the most numerous?

    • End-to-end tests
    • Unit tests
    • Manual tests
  2. What does assert.equal(1, "1") from the classic node:assert module do?

    • It fails
    • It passes, because it uses ==
    • It throws a TypeError
  3. Which is an edge case for an average function?

    • [10, 20]
    • An empty array
    • [12, 14, 16]

The rest of the course

  1. Node's Test Runner: Organizing Your Tests15 min
  2. Async Tests and Test Doubles (Mocks, Stubs, Spies)18 min
  3. TDD and Test Frameworks: Jest and Vitest18 min
  4. Integration Tests, Coverage, and Continuous Integration18 min

Automated Testing · Intermediate · 2 h 54 min