Federico Lelli / SchoolNode.js & Express
LEZIONE 31 · Affidabilità

Test automatici e casi limite

Prerequisito: lezione 30 e file persona.mjs. Trasforma gli esempi in verifiche ripetibili.

Che cosa stai verificando

Test unitario
Controlla una responsabilità piccola in isolamento, come la validazione di un body. È veloce e individua bene quale regola è stata violata.
Test di integrazione
Verifica la collaborazione tra componenti: parser, route, servizio e archivio. Può individuare un ordine errato dei middleware che un test della sola funzione non vedrebbe.
Asserzione e regressione
Un’asserzione confronta il comportamento con una proprietà attesa e fallisce se non coincide. Una regressione è un comportamento corretto che si rompe dopo una modifica; un test conservato ne rende visibile il ritorno.
Fixture e isolamento
Una fixture prepara dati iniziali noti. Un test isolato non dipende dall’ordine di esecuzione né dai dati lasciati da un altro test.

Il primo file di test

Salva come persona.test.mjs accanto a persona.mjs. Usa un runtime con node:test, per esempio Node 22 o successivo. Esegui node --test persona.test.mjs.

import test from 'node:test';
import assert from 'node:assert/strict';
import { validaPersona } from './persona.mjs';
test('normalizza senza modificare il body originale', () => {
  const body = { nome: ' Ada ', eta: 20, admin: true };
  assert.deepEqual(validaPersona(body), {
    ok: true, value: { nome: 'Ada', eta: 20 }
  });
  assert.equal(body.nome, ' Ada ');
});
for (const body of [null, [], {}, { nome: ' ', eta: 20 },
  { nome: 'Ada', eta: '20' }, { nome: 'Ada', eta: -1 },
  { nome: 'Ada', eta: 131 }, { nome: 'Ada', eta: 2.5 }]) {
  test('rifiuta ' + JSON.stringify(body), () => {
    assert.equal(validaPersona(body).ok, false);
  });
}
for (const eta of [0, 130]) {
  test('accetta il confine ' + eta, () => {
    assert.equal(validaPersona({ nome: 'Ada', eta }).ok, true);
  });
}

Risultato atteso

Undici test superati. Cambia intenzionalmente il limite massimo in 129: il test sul confine 130 deve fallire. Ripristina il codice dopo la prova. Un test che passa anche dopo aver rotto la regola probabilmente non sta verificando quella regola.

Non fermarti alla percentuale

La copertura misura codice attraversato, non la qualità delle asserzioni. Due test possono eseguire la stessa riga e verificare requisiti diversi. Scegli casi ordinari, confini, forme sbagliate e input vuoti a partire dal contratto.

Prova tu

Aggiungi test per un nome di 80 e 81 unità, e per NaN passato direttamente alla funzione. Poi prepara un test HTTP che distingua JSON malformato e dati invalidi. Quest’ultimo deve attraversare il parser, non chiamare soltanto validaPersona.

Riferimento: test runner di Node.js.

Materiali didattici curati e rielaborati da Federico Lelli. Le fonti e i riferimenti specifici sono indicati nei materiali disponibili.