Piramide o granchio? Trova una strategia di test adatta

Scopri come combinare diversi tipi di test in una strategia ragionevole che sia in linea con il tuo progetto.

Siamo felici di rivederti. L'ultimo articolo ha delineato molte basi su come approcciare i diversi tipi di test e i loro contenuti, oltre a chiarire le definizioni dei tipi di test. Ti ricordi di questa piccola immagine meme? Forse ti sei chiesto come possano funzionare insieme tutti i tipi di test che hai imparato.

Un armadietto con due cassetti che puoi aprire contemporaneamente.

Ora imparerai esattamente questo. Questo articolo fornisce un'introduzione su come combinare questi tipi di test in strategie ragionevoli e sceglierne una adatta al tuo progetto.

Puoi confrontare le strategie con una serie di forme per comprenderne meglio il significato. Di seguito è riportato un elenco di strategie con le rispettive dimensioni e gli ambiti di sviluppo.

Dimensioni applicazione Composizione del team Affidati ai test manuali Strategia di test
Piccola Solo sviluppatori Alta Test del cono di ghiaccio
Test del granchio
Piccola Sviluppatori e tecnici QA Alta Test del cono di ghiaccio
Test del granchio
Piccola Solo sviluppatori Bassa Piramide di prova
Large Solo sviluppatori Alta Trofeo di prova
Diamante di prova
Large Sviluppatori e tecnici QA Alta Trofeo di prova
Testa del granchio
Large Solo sviluppatori Bassa Trofeo di prova
A nido d'ape di prova

Diamo un'occhiata più da vicino alle strategie e scopriamo il significato dei nomi.

Determina gli obiettivi dei test: che cosa vuoi ottenere con questi test?

Prima di iniziare a creare una buona strategia, stabilisci il tuo obiettivo di test. Quando ritieni che la tua applicazione sia stata sufficientemente testata?

Ottenere un'elevata copertura dei test è spesso visto come l'obiettivo principale degli sviluppatori quando si tratta di test. Ma è sempre l'approccio migliore? Quando scegli una strategia di test, potrebbe esserci un altro fattore critico da considerare, ovvero soddisfare le esigenze degli utenti.

In qualità di sviluppatore, utilizzi anche molte altre applicazioni e dispositivi. A questo proposito, sei l'utente che si affida a tutti questi sistemi per "funzionare semplicemente". A sua volta, ti affidi a innumerevoli sviluppatori che fanno del loro meglio per far funzionare le loro applicazioni e i loro dispositivi. Per risolvere il problema, in qualità di sviluppatore devi anche cercare di mantenere questa fiducia. Quindi il tuo primo obiettivo dovrebbe essere sempre quello di fornire software funzionante e servire gli utenti. Questo si estende ai test che scrivi per garantire la qualità dell'applicazione. Kent C. Dodds riassume molto bene la questione nel suo post Static vs Unit vs Integration vs E2E Testing for Frontend Apps:

Più i test sono simili al modo in cui viene utilizzato il software, maggiore sarà la fiducia che potranno offrirti.

di Kent C. Dodd

Kent lo descrive come una ripresa d'affidabilità nei test. Più ti avvicini agli utenti scegliendo un tipo di test adatto, più puoi fidarti che i test hanno risultati validi. In altre parole, più in alto sali la piramide, maggiore sarà la tua sicurezza. Ma aspetta, cos'è la piramide?

Determinare le strategie di test: come scegliere una strategia di test

Come primo passo, determina quali parti dei requisiti devi verificare per assicurarti che siano soddisfatti. Scopri quali tipi di test utilizzare e a quale livello di dettaglio puoi ottenere la massima affidabilità mantenendo una struttura dei costi efficiente. Molti sviluppatori affrontano questo argomento utilizzando delle analogie. Ecco i più comuni, a partire dal famoso classico.

Molte forme come piramide, diamanti, cono di ghiaccio, favi e un trofeo, che rappresentano le strategie di test.

Il classico: la piramide di prova

Non appena inizierai a cercare le strategie di test, probabilmente ti imbatterai nella piramide dell'automazione dei test come prima analogia. Mike Cohn ha introdotto questo concetto nel suo libro "Succeeding with Agile". In seguito, Martin Fowler ampliò questo concetto nel suo articolo sulla piramide di prova pratica. Puoi rappresentare visivamente la piramide nel seguente modo:

La piramide di prova.

Come si vede in questo disegno, la piramide di test è costituita da tre livelli:

  1. Unità. Questi test si trovano nel livello base della piramide perché sono veloci da eseguire e semplici da mantenere. Sono isolate e prendono di mira le unità di test minori. Ad esempio, vedi un tipico test delle unità per un prodotto molto piccolo.

  2. Integrazione. Questi test si trovano al centro della piramide, perché hanno una velocità di esecuzione accettabile, ma ti avvicinano all'utente rispetto ai test delle unità. Un esempio di test di integrazione è un test API. Puoi anche classificare i test dei componenti in questo tipo.

  3. Test E2E (chiamati anche test della UI). Questi test simulano un utente reale e la sua interazione. L'esecuzione di questi test richiede più tempo e, di conseguenza, è più costoso. Si trovano nella parte superiore della piramide.

Fiducia rispetto alle risorse

Come abbiamo visto brevemente in precedenza, l'ordine dei livelli non è una coincidenza. Mostrano le priorità e i costi corrispondenti. In questo modo avrai un quadro chiaro del numero di test che dovresti scrivere per ogni livello. Lo hai già visto nella definizione dei tipi di test.

Poiché i test E2E sono più vicini ai tuoi utenti, ti offrono la massima certezza che l'applicazione funzioni come previsto. Tuttavia, richiedono uno stack di applicazioni completo e un utente simulato, pertanto sono anche potenzialmente i più costosi. Quindi la fiducia è nella competizione diretta con le risorse necessarie per eseguire i test.

La piramide di test con frecce che mostrano la direzione dell'affidabilità e delle risorse richieste per i diversi tipi di test.

La piramide cerca di risolvere questo problema facendoti concentrare maggiormente sui test delle unità e prioritizzando rigorosamente i casi coperti dai test E2E. ad esempio i percorsi più importanti degli utenti o i luoghi più vulnerabili ai difetti. Come Martin Fowler sottolinea, i due punti più essenziali della piramide di Cohn sono i seguenti:

  1. Scrivere test con granularità diversa.
  2. Più alto è il livello, minore è il numero di test che dovresti eseguire.

Piramide si è evoluta! Adattamenti delle piramidi di prova

Per diversi anni le discussioni hanno riguardato la piramide. La piramide sembra semplificare eccessivamente le strategie di test, esclude molti tipi di test e non è più adatta a tutti i progetti reali. Pertanto, potrebbe essere fuorviante. La piramide è caduta in forma? Guillermo Rauch ha un'opinione al riguardo:

Scrivere test. Non molti. Principalmente integrazione.

di Guillermo Rauch

È una delle citazioni più citate sull'argomento, quindi analizziamola:

  • "Scrivi test". Non solo perché crea fiducia, ma anche perché consente di risparmiare tempo nelle operazioni di manutenzione.
  • "Non troppe". Una copertura del 100% non è sempre una buona soluzione, perché i test non hanno la priorità e richiedono molte operazioni di manutenzione.
  • "Principalmente integrazione". Anche in questo caso l'attenzione è concentrata sui test di integrazione: sono quelli che rappresentano il valore aziendale più elevato in quanto offrono un elevato livello di confidenza giornaliero, mantenendo al contempo un tempo di esecuzione ragionevole.

In questo modo, rifletti sulla piramide di test e concentrati sui test di integrazione. Negli ultimi anni sono stati proposti molti adattamenti, quindi passiamo a quelli più comuni.

Diamante di prova

Il primo adattamento elimina l'eccessiva enfasi sul test delle unità, come mostrato nella piramide di test. Immagina di aver raggiunto il 100% di copertura per i test delle unità. Tuttavia, la prossima volta che eseguirai il refactoring, dovrai aggiornare molti di questi test delle unità e potresti avere la tentazione di saltarli. Così si erodono.

Di conseguenza, e insieme alla maggiore attenzione sui test di integrazione, potrebbe emergere la seguente forma:

Il rombo di prova.

Una piramide diventa un diamante. Puoi visualizzare i tre livelli precedenti, ma con una dimensione diversa, e il livello delle unità è stato tagliato:

  • Unità. Scrivi i test delle unità nel modo in cui li hai definiti prima. Tuttavia, poiché tendono a erodere, danno priorità e coprono solo i casi più critici.
  • Integrazione. I test di integrazione che conosci testano la combinazione di unità singole.
  • E2E. Questo livello gestisce i test dell'interfaccia utente in modo simile alla piramide di test. Ricordati di scrivere solo test E2E per gli scenari di test più critici.

Test a nido d'ape

C'è un altro adattamento, introdotto da Spotify, simile al diamante di test, ma ulteriormente specializzato per sistemi software basati su microservizi. Il nido d'ape di test è un'altra analogia visiva per la granularità, l'ambito e il numero di test da scrivere per un sistema software basato su microservizi. A causa delle loro dimensioni ridotte, la complessità più considerevole di un microservizio non risiede nel servizio stesso, ma nel modo in cui interagisce con gli altri. Pertanto, una strategia di test per un microservizio dovrebbe concentrarsi principalmente sui test di integrazione.

Il nido d'ape di prova.

Questa forma ci ricorda un nido d'ape, da cui deriva il nome. Dispone dei seguenti livelli:

  • Test integrati. L'articolo di Spotify utilizza una citazione di J. B. Rainsberger definisce questo livello: "Un test che supererà o avrà esito negativo in base alla correttezza di un altro sistema". Questi test hanno dipendenze esterne che devi considerare e, al contrario, il tuo sistema potrebbe essere una dipendenza che provoca un errore in altri sistemi. Analogamente ai test E2E in altre analogie, utilizzare questi test con cautela, solo per i casi più essenziali.
  • Test di integrazione. Come per altri adattamenti, dovresti concentrarti su questo livello. Contiene test che verificano la correttezza del servizio in modo più isolato, ma comunque in combinazione con altri servizi. Ciò significa che i test includeranno anche altri sistemi e si concentreranno sui punti di interazione, ad esempio tramite i test delle API.
  • Test sui dettagli di implementazione. Questi test sono simili a test delle unità, ovvero test che si concentrano su parti di codice che sono naturalmente isolate e quindi presentano una propria complessità interna.

Se vuoi saperne di più su questa strategia di test, consulta il post che confronta la piramide di prova con il nido d'ape di Martin Fowler e l'articolo originale di Spotify.

Trofeo di prova

Puoi già vedere uno stato attivo ricorrente per i test di integrazione. Tuttavia, un altro tipo che hai trovato nell'articolo precedente non è un test teorico, ma è comunque un aspetto importante che dovresti prendere in considerazione in una strategia di test. L'analisi statica non è presente nella piramide di test e nella maggior parte degli adattamenti che hai osservato finora. C'è l'adattamento al trofeo di test che prende in considerazione l'analisi statica senza perdere l'attenzione ai test di integrazione. Il trofeo di test è nato dalla citazione precedente di Guillermo Rauch ed è stato sviluppato da Kent C. S Dodd:

Il trofeo di test.

Il trofeo di test è un'analogia che illustra la granularità dei test in modo leggermente diverso. Ha quattro livelli:

  • Analisi statica. Svolge un ruolo fondamentale in questa analogia e ti permette di individuare gli errori di battitura e di stile e altri bug semplicemente eseguendo i passaggi di debug già descritti.
  • Test delle unità: Garantiscono che l'unità più piccola venga testata in modo appropriato, ma il trofeo di test non la metterà in evidenza quanto la piramide di prova.
  • Integrazione. Questo è l'obiettivo principale, in quanto bilancia il costo e la maggiore fiducia nel modo migliore, come nel caso di altri adattamenti.
  • Test dell'interfaccia utente. Includendo E2E e test visivi, si trovano in cima al trofeo di test, in modo simile al loro ruolo nella piramide di test.

Per ulteriori informazioni sul trofeo di test, leggi il post del blog di Kent C. Dodd su questo argomento.

Alcuni approcci più incentrati sull'interfaccia utente

È tutto perfetto, ma indipendentemente da come la chiami "piramide", "a nido d'ape" o "diamante", manca ancora qualcosa. Sebbene l'automazione dei test sia importante, è importante ricordare che i test manuali sono comunque essenziali. I test automatici dovrebbero alleggerire le attività di routine e consentire agli ingegneri del controllo qualità di concentrarsi sulle aree cruciali. Invece di sostituire i test manuali, l'automazione dovrebbe completarla. Esiste un modo per integrare i test manuali con l'automazione per ottenere risultati ottimali?

Test del cono di ghiaccio e del granchio

Esistono infatti due adattamenti della piramide di test che si concentrano maggiormente su queste modalità di test incentrate sull'interfaccia utente. Entrambi hanno il vantaggio di un'elevata affidabilità, ma sono naturalmente più costosi a causa di un'esecuzione del test più lenta.

Il primo, il cono di ghiaccio di prova, ha l'aspetto della piramide inversa. Senza la fase di prova manuale, è anche nota come pizza di prova.

Il cono di ghiaccio per le prove.

Il cono di ghiaccio è incentrato sui test manuali o dell'interfaccia utente e sui test delle unità. Spesso prende forma nei progetti in cui gli sviluppatori hanno iniziato a lavorare con poche riflessioni sulla strategia di test. Il codice di ghiaccio è considerato un anti-pattern e, giustamente, è costoso in termini di risorse e lavoro manuale.

Il granchio di prova è simile al cono di ghiaccio di prova, ma con maggiore enfasi sull'E2E e sui test visivi:

Il granchio collaudato.

Questa strategia di test include un altro aspetto: verifica che l'applicazione funzioni e sembrerà corretto. La ricerca del granchio evidenzia l'importanza dei test visivi, come descritto nell'articolo precedente. I test di integrazione, suddivisi in test dei componenti e dell'API, si spostano ulteriormente in background e il test delle unità svolge un ruolo ancora più secondario in questo caso. Puoi trovare ulteriori dettagli su questa strategia di test in questo articolo sul test del granchio.

Anche se sono più costose, queste due strategie di test hanno il loro posto: ad esempio, in progetti più piccoli dove sono necessari meno test o che è necessario coprire meno complessità. In questo caso, una strategia di test completa incentrata sui test di integrazione potrebbe essere troppo complessa.

Sebbene queste due strategie di test siano più costose, possono essere utili, ad esempio, nei progetti più piccoli che richiedono meno test e non devono coprire molta complessità. In questo caso, una strategia di test su vasta scala incentrata sui test di integrazione potrebbe essere inutilmente complessa.

Consiglio pratico: creiamo una strategia.

Ora hai appreso le strategie di test più comuni. Hai iniziato con il classico, la piramide di prova, e hai scoperto i suoi numerosi adattamenti. Ora devi valutarli per il tuo prodotto e decidere qual è il migliore per il tuo progetto. La risposta a questa domanda dovrebbe iniziare con l'opzione "Dipende" che tutti preferiscono. Tuttavia, questo non lo rende meno preciso.

Dipende.

La scelta della strategia di test più appropriata tra quelle descritte, e anche quelle omesse, dipende dalla tua applicazione. Dovrebbe adattarsi alla tua architettura, ai tuoi requisiti e, non meno importante, agli utenti e ai loro requisiti. Tutti questi dati possono variare da un'applicazione all'altra. È assolutamente normale. Ricorda che il tuo obiettivo più importante è servire gli utenti, non la definizione dei libri di testo.

Il più delle volte, i test reali sono difficili da separare e definire individualmente. Persino Martin Fowler sottolinea l'aspetto positivo delle definizioni differenti, come nel caso dei test delle unità. Come afferma correttamente Justin Searls nel suo tweet:

[...] scrivere test espressivi che stabiliscono confini chiari, vengono eseguiti rapidamente e in modo affidabile e non vanno a buon fine solo per motivi utili.

di Justin Searls

Concentrati sui test che segnalano errori effettivi che gli utenti potrebbero riscontrare e non distrarsi dal tuo obiettivo. I test dovrebbero essere pensati per aiutare l'utente, non solo per fornire una copertura totale o per discutere della percentuale di quale tipo di test scrivere.

Concentrati sui test che segnalano errori reali che gli utenti potrebbero riscontrare senza distrarsi dal tuo obiettivo. I test dovrebbero essere pensati per aiutare l'utente, non solo per fornire una copertura del 100% o per accendere dibattiti sulla percentuale di un particolare tipo di test che dovresti scrivere.