Scopri come combinare diversi tipi di test in una strategia ragionevole adatta al tuo progetto.
Siamo felici di rivederti. L'ultimo articolo ha fornito molte informazioni su come affrontare i diversi tipi di test e cosa contengono, nonché chiarito le definizioni dei tipi di test. Ricordi questa piccola immagine meme? Potresti chiederti come tutti questi tipi di test che hai appreso possano funzionare insieme.
A breve imparerai proprio questo. Questo articolo fornisce un'introduzione su come combinare questi tipi di test in strategie ragionevoli e scegliere quella più 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.
Diamo un'occhiata più da vicino alle strategie e scopriamo il significato dei loro nomi.
Determina gli obiettivi dei test: cosa vuoi ottenere con questi test?
Prima di iniziare a creare una buona strategia, devi capire qual è il tuo obiettivo di test. Quando ritieni che la tua applicazione sia stata testata a sufficienza?
Raggiungere una copertura dei test elevata è spesso considerato l'obiettivo finale per gli sviluppatori in materia di test. Ma è sempre l'approccio migliore? Quando decidi una strategia di test, potresti dover prendere in considerazione un altro fattore fondamentale: soddisfare le esigenze dei tuoi utenti.
In qualità di sviluppatore, utilizzi anche molti altri dispositivi e applicazioni. A questo proposito, sei l'utente che si affida a tutti questi sistemi per "funzionare e basta". A tua volta, ti affidi a innumerevoli sviluppatori che fanno del loro meglio per far funzionare le loro applicazioni e i loro dispositivi. Come sviluppatore, ti impegni a mantenere questa fiducia. Pertanto, il tuo primo obiettivo dovrebbe sempre essere quello di rilasciare un software funzionante e di soddisfare le esigenze dei tuoi utenti. Questo vale anche per i test che scrivi per garantire la qualità dell'applicazione. Kent C. Dodds lo riassume molto bene nel suo post Static vs Unit vs Integration vs E2E Testing for Frontend Apps:
Più i test rispecchiano il modo in cui viene utilizzato il software, più possono darti sicurezza.
di Kent C. Dodds
Kent lo descrive come un modo per acquisire fiducia nei test. Più ti avvicini agli utenti scegliendo un tipo di test adatto, più puoi fidarti che i tuoi test abbiano risultati validi. In altre parole, più sali nella piramide, più acquisisci sicurezza. Ma aspetta, che cos'è la piramide?
Determinazione delle strategie di test: come scegliere una strategia di test
Come primo passaggio, determina quali parti dei requisiti devi controllare 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 di costo efficiente. Molti sviluppatori affrontano questo argomento utilizzando analogie. Ecco le più comuni, a partire dal classico ben noto.
La classica piramide dei test
Non appena inizi a cercare strategie di test, probabilmente ti imbatterai nella piramide di automazione dei test come prima analogia. Mike Cohn ha introdotto questo concetto nel suo libro "Succeeding with Agile". In seguito, Martin Fowler ha ampliato il concetto nel suo articolo Practical Test Pyramid. Puoi rappresentare la piramide visivamente come segue:
Come mostrato in questo disegno, la piramide di test è composta da tre livelli:
Unità. Questi test si trovano nel livello di base della piramide perché sono rapidi da eseguire e semplici da gestire. Sono isolati e hanno come target le unità di test più piccole. Ad esempio, di seguito è riportato un tipico test di unità per un prodotto molto piccolo.
Integrazione. Questi test si trovano al centro della piramide, perché hanno una velocità di esecuzione accettabile, ma ti avvicinano all'utente più di quanto possano fare i test di unità. Un esempio di test di integrazione è un test API. Puoi anche classificare i test dei componenti come di questo tipo.
Test E2E (chiamati anche test UI). Questi test simulano un utente reale e la sua interazione. Questi test richiedono più tempo per l'esecuzione e sono quindi più costosi. Si trovano al vertice della piramide.
Fiducia e risorse
Come accennato 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 da scrivere per ogni livello. L'hai già visto nella definizione dei tipi di test.
Poiché i test E2E sono più vicini agli utenti, ti garantiscono 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. Pertanto, l'affidabilità è in diretta concorrenza con le risorse necessarie per eseguire i test.
La piramide cerca di risolvere questo problema incentrando la tua attenzione maggiormente sui test di unità e dando la priorità ai casi coperti dai test E2E. Ad esempio, i percorsi degli utenti più importanti o i punti più vulnerabili ai difetti. Come sottolinea Martin Fowler, i due punti più essenziali della piramide di Cohn sono i seguenti:
- Scrivi test con granularità diverse.
- Più alto è il livello, meno test dovresti avere.
Pyramid si è evoluto. Adattamenti delle piramidi di test
Per diversi anni, le discussioni hanno ruotato attorno alla piramide. La piramide sembra semplificare eccessivamente le strategie di test, tralascia molti tipi di test e non è più adatta a tutti i progetti reali. Pertanto, potrebbero essere fuorvianti. La piramide ha perso la forma? Guillermo Rauch ha un'opinione in merito:
Scrivi i test. Non troppi. Principalmente integrazione.
di Guillermo Rauch
È una delle citazioni più citate su questo argomento, quindi analizziamola:
- "Scrivi test". Non solo perché genera fiducia, ma anche perché consente di risparmiare tempo in termini di manutenzione.
- "Non troppi". La copertura al 100% non è sempre buona perché i test non hanno la priorità e la manutenzione sarà molto onerosa.
- "Per lo più integrazione". Anche in questo caso l'attenzione è rivolta ai test di integrazione: hanno il maggior valore commerciale perché forniscono un elevato livello di confidenza giornaliero mantenendo un tempo di esecuzione ragionevole.
Questo ti fa ripensare alla piramide dei test e spostare l'attenzione sui test di integrazione. Negli ultimi anni sono stati proposti molti adattamenti, quindi diamo un'occhiata a quelli più comuni.
Rombo di prova
La prima adattamento rimuove l'enfasi eccessiva sui test di unità, come mostrato nella piramide dei test. Immagina di aver raggiunto il 100% di copertura per i test delle unità. Tuttavia, la prossima volta che esegui il refactoring, dovrai aggiornare molti di questi test di unità e potresti essere tentato di saltarli. Quindi si erode.
Di conseguenza, e insieme all'attenzione maggiore ai test di integrazione, potrebbe emergere la seguente situazione:
Una piramide si trasforma in un diamante. Puoi vedere i tre livelli precedenti, ma con dimensioni diverse e il livello dell'unità è stato tagliato:
- Unità. Scrivi i test delle unità nel modo in cui li hai definiti in precedenza. Tuttavia, poiché tendono a erodersi, danno la priorità e coprono solo le richieste più critiche.
- Integrazione. I test di integrazione che conosci, che testano la combinazione di singole unità.
- E2E. Questo livello gestisce i test UI in modo simile alla piramide di test. Fai attenzione a scrivere test E2E solo per gli scenari di test più critici.
Test del nido d'ape
Esiste un'altra adattamento, introdotto da Spotify, simile al diamante di test, ma ulteriormente specializzato per i sistemi software basati su microservizi. La struttura a favo 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 si trova 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.
Questa forma ricorda un favo di miele, da cui il nome. Ha i seguenti livelli:
- Test integrati. L'articolo di Spotify utilizza una citazione di J. B. Rainsberger per definire questo livello: "Un test che supera o non supera la verifica in base alla correttezza di un altro sistema". Questi test hanno dipendenze esterne che devi prendere in considerazione e, al contrario, il tuo sistema potrebbe essere una dipendenza che danneggia altri sistemi. Analogamente ai test E2E in altre analogie, utilizza questi test con attenzione, solo per i casi più essenziali.
- Test di integrazione. Come per altre adattamenti, devi 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 API.
- Test sui dettagli di implementazione. Questi test sono simili ai test di unità, che si concentrano su parti di codice isolate naturalmente e che hanno quindi una propria complessità interna.
Per scoprire di più su questa strategia di test, consulta il post che mette a confronto la piramide di test con il favo di miele di Martin Fowler e l'articolo originale di Spotify.
Trofeo di test
Puoi già notare un'attenzione ripetuta sui test di integrazione. Tuttavia, un altro tipo che hai trovato nell'articolo precedente non è un test teorico, ma è comunque un aspetto importante da considerare in una strategia di test. L'analisi statica non è presente nella piramide di test e nella maggior parte delle adattamenti che hai visto finora. Esiste l'adattamento del trofeo di test che prende in considerazione l'analisi statica, pur mantenendo l'attenzione sui test di integrazione. Il trofeo di test è nato dalla citazione precedente di Guillermo Rauch ed è stato sviluppato da Kent C. Dodds:
Il trofeo di test è un'analogia che mostra la granularità dei test in un modo leggermente diverso. È composta da quattro livelli:
- Analisi statica. Svolge un ruolo fondamentale in questa analogia e ti consente di rilevare errori ortografici, errori di stile e altri bug semplicemente eseguendo i passaggi di debug già descritti.
- Test di unità. Garantiscono che l'unità più piccola venga testata in modo appropriato, ma il trofeo di test non le evidenzierà nella stessa misura della piramide di test.
- Integrazione. Questo è l'obiettivo principale, in quanto bilancia il costo e l'affidabilità in modo ottimale, come per altri adattamenti.
- Test dell'interfaccia utente. Sono inclusi i test E2E e visivi e si trovano al vertice del trofeo di test, in modo simile al loro ruolo nella piramide dei test.
Per scoprire di più sul trofeo per i test, consulta il post del blog di Kent C. Dodds su questo argomento.
Alcuni approcci più incentrati sull'interfaccia utente
Tutto bene, ma indipendentemente dal nome che dai alla tua strategia, "piramide", "a nido d'ape" o "a diamante", manca ancora qualcosa. Sebbene l'automazione dei test sia utile, è importante ricordare che i test manuali sono ancora essenziali. I test automatici dovrebbero sgravare le attività di routine e consentire agli addetti al controllo qualità di concentrarsi sulle aree cruciali. L'automazione non deve sostituire i test manuali, ma integrarli. Esiste un modo per integrare i test manuali con l'automazione per ottenere risultati ottimali?
Test del cono gelato e del granchio di test
Esistono infatti due adattamenti della piramide dei test che si concentrano maggiormente su questi metodi di test incentrati sull'interfaccia utente. Entrambi hanno il vantaggio di un'elevata affidabilità, ma sono naturalmente più costosi a causa dell'esecuzione più lenta dei test.
Il primo, il cono gelato di prova, assomiglia alla piramide capovolta. Senza il passaggio di test manuale, è nota anche come pizza di test.
Il cono gelato si concentra maggiormente sui test manuali o dell'interfaccia utente e meno sui test di unità. Spesso prende forma in progetti in cui gli sviluppatori hanno iniziato a lavorare con poche idee sulla strategia di test. Il codice ice è considerato un antipattern e giustamente. È costoso in termini di risorse e lavoro manuale.
Il granchio di test è simile al cono gelato di test, ma con maggiore enfasi sui test E2E e visivi:
Questa strategia di test include un altro aspetto: verifica che l'applicazione funzioni e abbia un aspetto corretto. Il granchio del test evidenzia l'importanza dei test visivi, definiti nell'articolo precedente. I test di integrazione, suddivisi in test di componenti e API, passano in secondo piano e i test di unità svolgono un ruolo ancora più secondario. Puoi trovare ulteriori dettagli su questa strategia di test in questo articolo sul granchio di test.
Sebbene siano più costose, queste due strategie di test hanno il loro posto: ad esempio, in progetti più piccoli in cui sono necessari meno test o in cui è necessario gestire una complessità inferiore. In questo caso, una strategia di test completa incentrata sui test di integrazione potrebbe essere eccessiva.
Sebbene queste due strategie di test siano più costose, hanno il loro posto, ad esempio in progetti più piccoli che richiedono meno test e non devono coprire una grande complessità. In questo caso, una strategia di test completa incentrata sui test di integrazione potrebbe essere inutilmente complessa.
Consiglio pratico: stiliamo una strategia.
Ora hai appreso le strategie di test più comuni. Hai iniziato con la classica piramide dei test e hai imparato a conoscere le sue numerose varianti. Ora devi valutarli per il tuo prodotto e decidere quale sia il migliore per il tuo progetto. La risposta a questa domanda dovrebbe iniziare con la frase più amata da tutti: "Dipende". Ciò non significa che non sia accurata.
La scelta della strategia di test più appropriata tra quelle descritte, e anche tra quelle escluse, dipende dalla tua applicazione. Deve essere adatta alla tua architettura, ai tuoi requisiti e, ultimo ma non meno importante, agli utenti e ai loro requisiti. Tutto ciò potrebbe variare da un'applicazione all'altra. È del tutto normale. Ricorda che il tuo obiettivo principale è soddisfare i tuoi utenti, non una definizione da manuale.
Il più delle volte, i test reali sono difficili da separare e definire singolarmente. Anche Martin Fowler stesso sottolinea l'aspetto positivo delle definizioni diverse, ad esempio nel caso dei test di unità. Come afferma correttamente Justin Searls nel suo tweet:
[…] scrivi test espressivi che stabiliscono confini chiari, vengono eseguiti in modo rapido e affidabile e non superano solo per motivi utili.
di Justin Searls
Concentrati sui test che segnalano gli errori effettivi che gli utenti potrebbero riscontrare e non lasciarti distrarre dal tuo obiettivo. I test devono essere progettati per essere utili all'utente, non solo per fornire una copertura del 100% o per discutere su quale percentuale di quale tipo di test scrivere.
Concentrati sui test che segnalano errori reali che potrebbero essere riscontrati dagli utenti e non lasciarti distrarre dal tuo obiettivo. I test devono essere progettati per essere utili all'utente, non solo per fornire una copertura del 100% o per suscitare dibattiti su quale percentuale di un determinato tipo di test scrivere.