modulo 07 / lezione 48
Leggere e verificare codice generato
Casi normali, casi limite, input ostili
Verificare comportamento e robustezza oltre il percorso felice.
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:
- classificare scenario in caso normale / limite / ostile;
- costruire una tabella di test che copre le tre categorie;
- 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/undefineddentro
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/123con 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:
- Caso normale: 1-3 test. Il “demo che mostri al cliente”.
- Edge case: 5-10 test. Scegli da categorie pertinenti.
- Input ostile: 3-5 test base (injection, manipolazione parametri).
- Test in CI: tutti questi devono passare a ogni commit.
- 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.
- 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.
- 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.
- 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.