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.
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
- Crea la struttura di cartelle
test/domain/,test/application/,test/infrastructure/,test/fakes/. - Sposta i test esistenti nelle cartelle corrette.
- Verifica che ogni file di test importi dalla posizione giusta (
../../src/...). - Esegui tutti i test e verifica che passino ancora.
- 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
- Crea le cartelle
test/domain/,test/application/,test/infrastructure/,test/fakes/. - Per ogni caso d’uso in
src/application/, verifica che esista il file test corrispondente. - Per ogni funzione di dominio in
src/domain/, verifica che esista il test corrispondente. - Esegui
npm teste leggi l’output: quanti test passano, quanti falliscono, quanti mancano? - 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
apriSegnalazioneGuastose 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 testesegue 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.