modulo 08 di 24 / Ore 0-20

Moduli 1-8 / Checkpoint 20 ore

Scrivere i primi test sulle regole

Scrivere test minimi sulle regole del dominio per proteggere il refactoring della versione essenziale.

30 min Architettura del software

Scrivere i primi test sulle regole

Arrivati al primo taglio architetturale, abbiamo bisogno di una rete di sicurezza.

Non serve una suite enorme.

Servono test minimi sulle regole piu importanti.

I test ci aiutano a fare refactoring senza rompere il comportamento.

Obiettivo

Alla fine devi avere almeno alcuni test o scenari eseguibili su:

  • creazione di uno strumento valido;
  • rifiuto di uno strumento senza nome;
  • rifiuto del prestito di uno strumento non disponibile;
  • rifiuto della chiusura doppia di un prestito.

Se il progetto non ha ancora un test runner, puoi scrivere scenari manuali strutturati.

Ma l’obiettivo e arrivare presto a test automatici.

Cosa testare prima

Non testare subito tutto.

Parti dalle regole che, se rotte, rendono il registro inaffidabile:

Uno strumento deve avere un nome.
Solo uno strumento disponibile puo essere prestato.
Un prestito chiuso non puo essere chiuso di nuovo.
Uno stato strumento deve essere valido.

Queste regole stanno nel dominio.

Quindi possiamo testarle senza UI.

Esempio: strumento senza nome

Scenario:

Dato un comando senza nome,
quando creo uno strumento,
allora ottengo NOME_STRUMENTO_OBBLIGATORIO.

Test possibile:

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

test("uno strumento deve avere un nome", () => {
  expect(() =>
    creaStrumento({
      id: "s-001",
      nome: "",
      categoria: "robotica",
      stato: "disponibile",
    })
  ).toThrow("NOME_STRUMENTO_OBBLIGATORIO");
});

Esempio: strumento non prestabile

import { verificaStrumentoPrestabile } from "../src/domain/strumento.js";
import { StatoStrumento } from "../src/domain/statoStrumento.js";

test("uno strumento guasto non puo essere prestato", () => {
  const strumento = {
    id: "s-001",
    nome: "Proiettore",
    categoria: "video",
    stato: StatoStrumento.GUASTO,
  };

  expect(() => verificaStrumentoPrestabile(strumento)).toThrow(
    "STRUMENTO_NON_PRESTABILE"
  );
});

Questo test non apre il browser.

Non clicca un bottone.

Verifica la regola.

Esempio: prestito chiuso due volte

import { chiudiPrestito } from "../src/domain/prestito.js";

test("un prestito chiuso non puo essere chiuso di nuovo", () => {
  const prestito = {
    id: "p-001",
    strumentoId: "s-001",
    assegnatario: "Luca 3A",
    apertoIl: "2026-05-09",
    chiusoIl: "2026-05-10",
    stato: "chiuso",
  };

  expect(() => chiudiPrestito(prestito, "2026-05-11")).toThrow(
    "PRESTITO_GIA_CHIUSO"
  );
});

Questo test protegge lo storico dei prestiti.

Se non hai un test runner

Puoi creare una scheda:

# Test manuali minimi

## Test 1

Nome:
Strumento senza nome

Scenario:
Creo uno strumento con nome vuoto.

Risultato atteso:
Errore NOME_STRUMENTO_OBBLIGATORIO.

Risultato ottenuto:
...

Non e potente come un test automatico, ma e meglio di “ho cliccato un po’ e sembra funzionare”.

Test sui casi d’uso

Se hai tempo, aggiungi un test su RegistraPrestito con archivi in memoria.

Scenario:

Dato uno strumento disponibile,
quando registro un prestito,
allora lo strumento diventa in_prestito e nasce un prestito aperto.

Questo test verifica il coordinamento applicativo.

Non sostituisce i test del dominio.

Li affianca.

Cosa non testare ora

Nel checkpoint 20 ore non e necessario testare:

  • grafica;
  • colori;
  • layout;
  • localStorage;
  • API;
  • database;
  • casi avanzati di sicurezza;
  • prestazioni.

Per ora vogliamo proteggere le regole principali.

Esercizio

Scrivi almeno tre test o tre scenari manuali:

  1. strumento senza nome;
  2. strumento guasto non prestabile;
  3. prestito chiuso non richiudibile.

Per ogni test indica:

  • nome;
  • dati iniziali;
  • azione;
  • risultato atteso;
  • errore atteso, se presente.

Cosa produrre

Alla fine della lezione devi avere:

  • almeno tre test o scenari;
  • almeno due test sul dominio;
  • almeno un test candidato su un caso d’uso;
  • nessun test che dipende dal DOM per verificare regole;
  • nota nel README su come eseguire o leggere i test.

Spiegazione guidata per studiare

Questa lezione va studiata su due piani. Il primo è il comportamento visibile del Registro del laboratorio: che cosa vede o fa l’utente quando registra uno strumento, cerca un dispositivo, apre un prestito o segnala un guasto. Il secondo è il confine architetturale: dove deve stare il codice che rende possibile quel comportamento.

Per scrivere i primi test sulle regole, il punto centrale è questo: Un test è una piccola prova ripetibile. Nel corso serve soprattutto a proteggere regole e refactoring, non a inseguire una percentuale astratta.

Il rischio tipico è testare solo il caso felice. In architettura sono spesso più importanti i casi che devono essere rifiutati. Per evitarlo, non partire dal file che hai già aperto nell’editor. Parti dalla domanda: “quale responsabilità sto modificando?”. Se la risposta riguarda una regola del laboratorio, guarda il dominio. Se riguarda una sequenza di operazioni, guarda i casi d’uso. Se riguarda salvataggio, file, localStorage, API o database, guarda l’infrastruttura. Se riguarda input, pulsanti, form e messaggi, guarda la Presentation.

Il tempo è sufficiente per alternare spiegazione, modifica guidata e revisione. Alla fine della lezione lo studente non deve ricordare una definizione a memoria: deve saper indicare un punto del progetto, spiegare perché quel codice sta lì e mostrare una verifica del comportamento.

Passo per passo nel progetto

  1. Rileggi il titolo della lezione e riscrivilo come domanda pratica. Per esempio: “dove deve stare questa regola?”, “chi deve salvare questo dato?”, “come verifico questo errore?”.
  2. Apri solo i file necessari. Se devi toccare più di tre file, fermati e scrivi prima una mini-mappa.
  3. Scrivi il comportamento in una frase.
  4. Prepara dati minimi per lo scenario.
  5. Esegui l’azione.
  6. Controlla risultato, errore o stato finale.
  7. Aggiorna una nota breve nel README o negli appunti se hai cambiato un confine del progetto.

Esempio da leggere lentamente

Questo esempio serve a ragionare, non a incollare codice senza capire:

test("non apre un prestito per uno strumento guasto", () => {
  const archivio = archivioFintoConStrumento({ stato: "guasto" });
  expect(() => registraPrestito({ strumentoId: "str-1" }, archivio))
    .toThrow("STRUMENTO_GUASTO_NON_PRESTABILE");
});

Leggilo chiedendoti che cosa cambierebbe se domani sostituissimo la pagina web con una CLI, oppure localStorage con un’API. Se l’esempio continua ad avere senso senza riscrivere tutto, il confine è probabilmente buono. Se invece un dettaglio tecnico si propaga in molti file, il progetto sta tornando fragile.

Prova di comprensione

Prima di chiudere la lezione, rispondi per iscritto a queste domande:

  • Qual è la responsabilità principale trattata in questa lezione?
  • In quale livello del progetto dovrebbe stare?
  • Quale errore faresti se cercassi la soluzione più veloce?
  • Quale piccolo test, controllo manuale o esempio dimostra che hai capito?
  • Che cosa deve restare facile da cambiare dopo questa lezione?

Una risposta accettabile non deve essere lunga. Deve però usare parole concrete del Registro: strumento, prestito, stato, archivio, caso d’uso, messaggio, test.

Controllo finale

La lezione e completata quando puoi rispondere si:

  • ho testato almeno una regola del dominio;
  • ho testato almeno un errore;
  • non ho bisogno della UI per verificare la regola;
  • so quali test mancano;
  • i test mi aiutano a fare refactoring.

Nella prossima lezione prepariamo README e mappa del progetto.