modulo 07 / lezione 48

Leggere e verificare codice generato

Casi normali, casi limite, input ostili

Verificare comportamento e robustezza oltre il percorso felice.

75 min Vibe Coding

Casi normali, casi limite, input ostili

Il codice generato gestisce il caso normale. Spesso ignora i casi limite. Quasi sempre non considera input ostili. Tre categorie di test, tre livelli di robustezza. Senza esplorarle tutte, hai un’app che fa la demo bene e si rompe a contatto col mondo reale.

Perché questa lezione conta

Demo riuscita ≠ app robusta. Utenti reali fanno cose impreviste: lasciano campi vuoti, copiano-incollano testi enormi, premono submit due volte, perdono connessione, usano browser strani. Attaccanti fanno cose deliberatamente sbagliate: SQL injection, XSS, manipolazione parametri. Coprire le tre categorie è il salto da prototipo a software che regge.

Obiettivo operativo

Alla fine devi saper:

  1. classificare scenario in caso normale / limite / ostile;
  2. costruire una tabella di test che copre le tre categorie;
  3. scegliere quanti test scrivere per ciascuna in base alla criticità.

Nucleo della lezione

1. Caso normale (happy path)

Cosa è: l’utente collaborativo fa cose attese, dati validi, sistema funzionante.

Esempio: form contatto, email valida, messaggio < 500 caratteri, internet ok, server risponde 200, email arriva.

Test richiesti: 1-3. Il caso più comune dovrebbe essere stupidamente facile da testare. Se il caso normale richiede setup complesso, l’app è troppo complicata.

Cosa controlli: comportamento atteso, output corretto, tempi accettabili.

2. Caso limite (edge case)

Cosa è: scenari rari ma plausibili. Non patologici, solo non centrali.

Categorie tipiche:

Stringhe:

  • vuota
  • molto lunga (10K caratteri)
  • con caratteri unicode strani (emoji, RTL)
  • con whitespace solo
  • con leading/trailing whitespace
  • con caratteri speciali (<, &, ', ", \)

Numeri:

  • zero
  • negativo
  • molto grande (overflow)
  • molto piccolo (precisione)
  • non intero quando atteso intero

Liste/array:

  • vuoto
  • un solo elemento
  • molti elementi (10K+)
  • con duplicati
  • con null/undefined dentro

Date:

  • inizio/fine anno
  • DST transition
  • timezone diversa
  • futuro lontano / passato lontano
  • 29 febbraio in anno bisestile

Stati:

  • prima volta che si carica (no dati)
  • dopo logout/scadenza sessione
  • dopo refresh durante operazione in corso
  • multi-tab (modifica simultanea)

Rete:

  • request timeout
  • response 4xx
  • response 5xx
  • response malformata
  • offline durante invio

Per ogni feature: scegli 5-10 edge case dalle categorie pertinenti. Test per ciascuno.

3. Input ostile

Cosa è: utente che fa deliberatamente cose sbagliate. Per gioco, curiosità, o malizia.

Categorie:

Injection:

  • SQL: '; DROP TABLE users; --
  • HTML/XSS: <script>alert(1)</script>, <img src=x onerror=alert(1)>
  • Command: ; rm -rf /
  • Prompt injection (per app AI): “Ignora istruzioni precedenti…”

Manipolazione parametri:

  • ID di altri utenti in URL (/orders/123 con id non tuo)
  • ruolo nascosto in body request ({role: 'admin'})
  • prezzo manipolato ({price: 0.01} invece di server-derived)
  • query string aggiunte (?admin=1)

Volume:

  • file enormi (1GB upload)
  • liste lunghe (10M elementi)
  • ripetuta velocemente (rate abuse)
  • payload nested deeply (parser stack overflow)

Encoding:

  • UTF-8 con caratteri speciali per bypass filtri
  • doppia URL-encoding
  • null byte (%00) per troncamento path
  • tag chiusi/aperti malformati

Autenticazione:

  • JWT manipolato
  • cookie cancellato/modificato
  • request senza header expected
  • replay attack (stesso token più volte)

Test richiesti: dipende dalla criticità. Per app commerce/pagamenti: alta priorità. Per script personale: irrilevante.

Procedura pratica

Per ogni feature significativa:

  1. Caso normale: 1-3 test. Il “demo che mostri al cliente”.
  2. Edge case: 5-10 test. Scegli da categorie pertinenti.
  3. Input ostile: 3-5 test base (injection, manipolazione parametri).
  4. Test in CI: tutti questi devono passare a ogni commit.
  5. Documenta scelte: cosa hai deliberatamente NON testato (es. “fuzzing rete: out of scope MVP”).

Laboratorio guidato

Feature: form di contatto con campi nome, email, messaggio, invio email a admin.

Caso normale (3 test):

  • nome “Mario”, email mario@example.com, messaggio “Ciao” → email inviata, conferma utente.
  • form vuoto → errori inline su tutti i campi.
  • 3 invii in 1 minuto → primo successo, ultimi due bloccati per rate limit.

Edge case (10 test):

  • nome con accenti italiani (“Niccolò”) → ok.
  • email con + (mario+filter@example.com) → ok (è valida).
  • email con dominio molto lungo (200 caratteri) → ok o errore con messaggio chiaro.
  • nome vuoto, email valida → errore solo su nome.
  • messaggio 500 caratteri (limite) → ok.
  • messaggio 501 caratteri → errore con count.
  • caratteri unicode emoji nel messaggio → ok, salvato fedelmente.
  • whitespace solo nel messaggio → trattato come vuoto.
  • invio durante perdita rete → messaggio “riprova” + bottone retry.
  • doppio click submit → solo un invio (debounce).

Input ostile (5 test):

  • SQL injection in nome ('; DROP TABLE...) → input accettato come stringa, salvato come testo, no esecuzione.
  • XSS in messaggio (<script>alert(1)</script>) → mostrato come testo, non eseguito.
  • Email malformata (mario@) → respinta server-side anche se passa client.
  • Messaggio 100K caratteri → respinto con 413 Payload Too Large.
  • 100 invii in 1 minuto da stesso IP → rate limit (429) dopo soglia.

Tabella che copre 3 categorie, 18 scenari. Ognuno → 1 test. Coverage seria.

Output atteso

Una tabella test riusabile per la prossima feature, con righe (categorie) e colonne (scenario, comportamento atteso, comportamento osservato, severità). Documento di test plan compatto.

Studio passo passo

Studia questa lezione in tre passaggi, senza correre subito al prompt o al codice.

  1. Prima lettura: chiarisci l’obiettivo: verificare comportamento e robustezza oltre il percorso felice. Se non riesci a riscriverlo in una frase tua, rileggi il nucleo della lezione.
  2. Seconda lettura: trasforma i contenuti in domande operative:
  • Casi normali: dati attesi, flusso completo, utente collaborativo, rete funzionante.
  • Casi limite: stringhe vuote, valori massimi, assenza di dati, duplicati, date strane, lentezza.
  • Input ostili: script, SQL-like, file enormi, richieste non autorizzate, manipolazione parametri.
  1. Applicazione: svolgi il laboratorio: costruire una tabella di test manuali per una form o una API, includendo almeno tre input ostili. L’output da ottenere è: una checklist di test per non limitarsi alla demo che funziona una sola volta.

Prima di passare alla lezione successiva, controlla di avere un artefatto concreto: una tabella, un prompt, una checklist, un mini report, un diff commentato o una decisione scritta. Nel vibe coding la comprensione resta astratta finché non produce una traccia verificabile.

Checklist di verifica

  • riconosco le 3 categorie a colpo d’occhio;
  • ho scritto test per le 3 categorie su almeno una feature recente;
  • ho deliberatamente provato almeno un input ostile sul mio progetto;
  • la mia checklist edge case copre stringhe, numeri, liste, date, stati, rete.

Errori comuni

Solo happy path. “Funziona se tutto va bene”. Failures = produzione.

“Edge case sono per dopo”. Quasi mai arriva il “dopo”. Almeno scegli i 3 più probabili e coprili.

Ignorare input ostile su feature pubbliche. Forme pubbliche vengono attaccate. Sempre.

Test che dipende da rete reale. Test fragile, lento. Mock + integration test separato.

Test del 100% dei casi limite immaginabili. Paralisi. Pareto: 5-10 test critici per feature.

Validation solo client. Lezione 26. Il prossimo test ostile lo dimostrerà.

Prompt di lavoro

Genera tabella di test per questa feature: [descrizione]

Codice rilevante:
[incolla file/funzioni]

Voglio test per le 3 categorie:

1. Caso normale (3 test): scenari attesi, dati validi, sistema funzionante.

2. Edge case (8-10 test): non patologici ma plausibili. Considera:
   - stringhe (vuota, lunga, unicode, whitespace, speciali)
   - numeri (zero, negativo, overflow, decimali)
   - liste (vuota, singola, lunga, con null)
   - date (DST, timezone, bisestile)
   - stati (primo caricamento, sessione scaduta)
   - rete (timeout, 4xx, 5xx)

3. Input ostile (4-5 test base):
   - SQL injection
   - XSS
   - manipolazione parametri (ownership)
   - volume (rate, payload size)

Output: tabella con colonne [categoria, scenario, input, comportamento atteso, severità].

NON scrivere codice di test ancora. Voglio prima validare gli scenari.

Esercizio finale

Per il tuo progetto attivo: prendi una feature pubblica. Provala come utente ostile per 10 minuti. Manipola URL, invia campi vuoti, doppi submit, copia-incolla testi enormi, modifica payload con devtools. Conta quanti scenari rompono il sistema in modo non grazioso. Se trovi più di 2-3 problemi, è prevenibile. Aggiungi quei test alla tabella e fixa.