Tag: testing, unit-test, integration-test, e2e, tdd, mock, qa, jest
Livello: intermedio
TL;DR: Sintesi rapida su piramide dei test, strategie di test (unitari, integrazione, E2E) e pattern fondamentali per rispondere a colloqui tecnici.
Piramide dei test: base ampia di test unitari veloci, livello intermedio di integrazione, vertice contenuto di test E2E.
Test unitari: verifica dell'isolamento di una singola funzione logica senza dipendenze esterne.
Test di integrazione: verifica dell'interazione reale o semi-reale tra due o piu' moduli o servizi.
Test E2E: simulazione dell'esperienza utente end-to-end sull'intera applicazione funzionante.
Pattern AAA: struttura chiara divisa in Arrange (setup), Act (esecuzione), Assert (verifica).
Test Doubles: Dummy (riempitivo), Stub (risposta prefissata), Spy (registra chiamate), Mock (verifica aspettative), Fake (implementazione leggera).
Test-Driven Development (TDD): ciclo Red (scrivi test che fallisce), Green (codice minimo funzionante), Refactor (ottimizza).
Code Coverage: metrica quantitativa (linee o rami coperti), non garanzia di assenza di bug o casi limite.
Q: Qual e' la differenza tra mock e stub?R: Uno stub fornisce dati preconfezionati per far proseguire l'esecuzione; un mock verifica anche che determinate interazioni o chiamate avvengano con parametri specifici.
Q: Quando preferisci i test di integrazione rispetto a quelli unitari?R: Quando devo validare flussi critici di persistenza su database, contratti API o coordinamento tra servizi che i mock unitari potrebbero mascherare.
Q: Come approcci il testing di codice legacy senza test?R: Individuo prima i punti di ingresso critici, creo test di caratterizzazione black-box per bloccare il comportamento attuale, poi inizio il refactoring a piccoli passi.
Q: Come eviti i test fragili (flaky tests) negli E2E?R: Evito timeout statici (sleep), uso attese esplicite sullo stato del DOM o sulla risposta di rete, e mantengo i selettori isolati via data-testid dedicati.
Q: Come decidi quando fermarti con la coverage?R: Punto alla copertura dei percorsi critici e logiche di business complesse piuttosto che al 100% cieco, che spesso produce test rigidi e costosi da mantenere.
Testare i dettagli implementativi invece del contratto e del comportamento pubblico.
Abuso di mock che rende il test verde anche a fronte di contratti API rotti in produzione.
Test interdipendenti in cui l'ordine di esecuzione altera lo stato globale o il database condiviso.
Asserzioni multiple su flussi non correlati all'interno dello stesso blocco di test.
Utilizzo di timer arbitrari nei test asincroni al posto di listener o polling sullo stato.
```describe('calculateDiscount', () => {
it('should apply tier discount for premium accounts', () => {
// Arrange
const cart = { total: 100, isPremium: true };
// Act
const finalPrice = calculateDiscount(cart);
// Assert
expect(finalPrice).toBe(80);
});
});
npm test -- --coverage --testPathPattern="services/order"
```
[ ] Differenze architetturali tra Mockist (London school) e Classicist (Detroit school) nel TDD
[ ] Strategie per database teardown e isolamento delle transazioni nei test di integrazione
[ ] Pattern di contract testing (es. Pact) tra architetture a microservizi
[x] Configurazione base di Jest/Vitest con setupFilesAfterEnv
[x] Convenzioni dei selettori per testing library (getByRole, getByTestId)