modulo 13 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Organizzare una piccola suite di test

Come strutturare la suite di test del Registro: file separati per dominio e application, naming convention, ordine di esecuzione e come aggiungere nuovi test in modo coerente.

25 min Architettura del software

Organizzare una piccola suite di test

Questa lezione appartiene al Modulo 13 — Testare l’architettura.

Obiettivo della lezione

Strutturare i test del Registro in modo che siano facili da trovare, capire ed eseguire. Alla fine la cartella test/ rispecchia la struttura di src/ e ogni file di test ha un ruolo chiaro.

Perché serve nel percorso

Una suite disorganizzata è difficile da mantenere: non si sa dove aggiungere un nuovo test, i nomi si ripetono, i test si interferiscono. Una suite ben strutturata è documentazione viva del progetto.

Nel Registro del laboratorio

Struttura consigliata:

test/
  domain/
    strumento.test.js          — test delle funzioni pure del dominio
    prestito.test.js           — test delle regole sui prestiti
  application/
    registraStrumento.test.js  — test del caso d'uso registraStrumento
    registraPrestito.test.js   — test del caso d'uso registraPrestito
    chiudiPrestito.test.js     — test del caso d'uso chiudiPrestito
    cercaStrumenti.test.js     — test del caso d'uso cercaStrumenti
  infrastructure/
    strumentoMapping.test.js   — test del mapping domain↔DTO
    prestitoMapping.test.js    — test del mapping domain↔DTO
  fakes/
    archivioStrumentiFake.js   — fake repository (non test, ma helper)
    archivioPrestitiFake.js    — fake repository

Questa struttura segue esattamente i livelli del progetto. Se aggiungi un caso d’uso in src/application/, aggiungi il test in test/application/. Non devi decidere ogni volta dove mettere il file.

Procedura guidata

  1. Crea la struttura di cartelle test/domain/, test/application/, test/infrastructure/, test/fakes/.
  2. Sposta i test esistenti nelle cartelle corrette.
  3. Verifica che ogni file di test importi dalla posizione giusta (../../src/...).
  4. Esegui tutti i test e verifica che passino ancora.
  5. Aggiorna il README con la struttura della suite.

Attività in classe

Parti da questa suite disorganizzata e riorganizzala:

test/
  test1.js          — contiene test di strumento e registraPrestito mescolati
  test-ui.js        — test che aprono localStorage direttamente
  prova.js          — test scritti per capire il codice, mai cancellati
  mapping.js        — test del mapping

Per ogni file: identifica di quale livello tratta, sposta nella cartella corretta e rinomina secondo la naming convention.

Compila la scheda:

## Riorganizzazione della suite

File originali:

File spostati in:

Test rimossi (e perché):

Risultato dopo la riorganizzazione (tutti passano?):

Spiegazione guidata per studiare

Ogni livello del Registro ha test con caratteristiche diverse:

Test di dominio — i più semplici. Testano funzioni pure senza dipendenze:

// test/domain/strumento.test.js
import { validaNomeStrumento } from "../../src/domain/strumento.js";

test("validaNomeStrumento — accetta nome di 2 caratteri", () => {
  expect(validaNomeStrumento("AB")).toBe("AB");
});

test("validaNomeStrumento — lancia NOME_STRUMENTO_NON_VALIDO per nome di 1 carattere", () => {
  expect(() => validaNomeStrumento("A")).toThrow("NOME_STRUMENTO_NON_VALIDO");
});

Nessun fake, nessuna dipendenza. Il test è velocissimo e non può fallire per ragioni esterne.

Test di application — usano i fake repository:

// test/application/chiudiPrestito.test.js
import { creaArchivioPrestitiFake } from "../fakes/archivioPrestitiFake.js";
import { chiudiPrestito } from "../../src/application/chiudiPrestito.js";

describe("chiudiPrestito", () => {
  test("imposta la data di chiusura sul prestito", () => {
    const prestito = { id: "p1", strumentoId: "s1", studenteId: "stu1", apertura: new Date(), chiusura: null };
    const archivio = creaArchivioPrestitiFake([prestito]);

    chiudiPrestito({ prestitoId: "p1" }, archivio);

    const chiuso = archivio.trovaPerId("p1");
    expect(chiuso.chiusura).toBeInstanceOf(Date);
  });

  test("lancia PRESTITO_GIA_CHIUSO per prestito già chiuso", () => {
    const prestito = { id: "p1", strumentoId: "s1", studenteId: "stu1", apertura: new Date(), chiusura: new Date() };
    const archivio = creaArchivioPrestitiFake([prestito]);

    expect(() => chiudiPrestito({ prestitoId: "p1" }, archivio)).toThrow("PRESTITO_GIA_CHIUSO");
  });
});

Test di infrastructure/mapping — verificano la conversione tra formati:

// test/infrastructure/strumentoMapping.test.js
import { strumentoToDTO, dtoToStrumento } from "../../src/infrastructure/mapping/strumentoMapping.js";

test("round-trip: domain → DTO → domain conserva tutti i campi", () => {
  const originale = { id: "s1", nome: "Trapano", categoria: "Utensile", stato: "disponibile" };
  const ricostruito = dtoToStrumento(strumentoToDTO(originale));
  expect(ricostruito).toEqual(originale);
});

Ordine di esecuzione: non importa per i test ben scritti. Ogni test deve essere indipendente. Se l’ordine conta, c’è un problema di stato condiviso da risolvere.

Passo per passo nel progetto

  1. Crea le cartelle test/domain/, test/application/, test/infrastructure/, test/fakes/.
  2. Per ogni caso d’uso in src/application/, verifica che esista il file test corrispondente.
  3. Per ogni funzione di dominio in src/domain/, verifica che esista il test corrispondente.
  4. Esegui npm test e leggi l’output: quanti test passano, quanti falliscono, quanti mancano?
  5. Aggiungi il test mancante più importante (quello che protegge la regola più critica).

Prova di comprensione

  • Perché i test di dominio non usano fake repository?
  • Cosa succede se due test condividono un’istanza di fake senza resettarla?
  • Come si aggiunge un nuovo test per un nuovo caso d’uso?
  • Dove si mette il test per apriSegnalazioneGuasto se non esiste ancora?

Errori da evitare

  • mettere tutti i test in un unico file — diventa ingestibile quando crescono;
  • avere test che dipendono dall’ordine di esecuzione — ogni test deve essere indipendente;
  • dimenticare di spostare i test quando si sposta il codice sorgente;
  • non aggiornare gli import dopo aver spostato i file.

Prodotto da consegnare

La cartella test/ riorganizzata con la struttura a specchio di src/, tutti i test esistenti spostati nelle cartelle corrette, e almeno un nuovo test aggiunto per una regola non ancora coperta.

Checklist di chiusura

  • test/domain/, test/application/, test/infrastructure/, test/fakes/ esistono
  • ogni caso d’uso ha il suo file di test
  • i test di dominio non importano fake o infrastruttura
  • i test di application usano i fake repository
  • npm test esegue tutti i test senza errori di import
  • la struttura della suite è documentata nel README

Risultato atteso

Ho riorganizzato la suite di test in test/domain/, test/application/, test/infrastructure/.
Ogni caso d'uso del Registro ha il proprio file di test.
I test di dominio non usano fake — sono puri.
I test di application usano archivioStrumentiFake e archivioPrestitiFake.
npm test esegue tutti i test e mostra l'output per livello.