Cosa testare e il tuo approccio

Cosa eseguire il test, al contrario di cosa è, è una domanda importante per tutti i team. Il test è un mezzo per raggiungere un obiettivo e scegliere come dare la priorità ai test di diverse parti del tuo codebase può essere difficile.

Il modo migliore per assegnare le priorità si basa sul codebase e sugli obiettivi del team. È importante ricordare, tuttavia, che sebbene sia necessario poco tempo e larghezza di banda per scrivere molti piccoli test (in fondo alla piramide di test, ad esempio i test delle unità) con un'elevata copertura del codice, non riducono necessariamente il rischio complessivo per il tuo progetto.

Test delle unità riuscito: il riquadro a scomparsa si apre. Test di integrazione non riuscito: il cassetto colpisce la maniglia di un altro cassetto e non riesce a continuare ad aprirsi.
Un esempio di come i test delle unità da soli non sono utili.

Puoi scegliere quali elementi testare per primo pensando ai casi d'uso principali della tua applicazione, del tuo sito web o della tua libreria. Potresti scrivere test dei componenti su parti critiche del tuo sito, i componenti fondamentali alla base dell'esperienza dell'utente. Ad esempio, gli sviluppatori di un sito che consente agli utenti di caricare e gestire dati di serie temporali dovrebbero immaginare e testare i diversi modi in cui un utente potrebbe eseguire queste attività.

Un altro approccio per l'assegnazione delle priorità consiste nell'ottenere il maggior numero di informazioni. Se il tuo codebase è "pericoloso", legacy o scritto in modo errato, può essere utile creare dei test al riguardo per rendere il suo comportamento più coerente prima di ignorarlo ulteriormente o eseguire un refactoring per correggerlo. È come un'impalcatura per un edificio già stato condannato, ma che ospita ancora il tuo data center.

Dimensionalità

Abbiamo introdotto il concetto di piramide di test o un'altra forma di test, ma tendono a presentare una sola dimensione dei test: una linea che va da un ambito di piccole dimensioni, da semplici test delle unità a test complessi e ad ampio raggio, dai test delle unità ai test di integrazione rispetto ai test end-to-end.

Tuttavia, alcuni dei lunghi elenchi di possibili tipi di test non rappresentano un livello di complessità, ma obiettivi o tecniche di test. Ad esempio, i test fumo sono una categoria diversa di test che possono a loro volta essere test unitari, end-to-end o di altro tipo, ma hanno lo scopo di fornire ai tester la certezza complessiva che il progetto in fase di test si trova in uno stato valido. I test visivi possono essere utili anche applicati a un piccolo componente o all'intero sito.

Il tuo codebase avrà requisiti unici. Ad esempio, potrebbe essere molto più importante nel tuo codebase allinearsi a una singola funzionalità, scrivere diversi tipi di test per assicurarsi che funzioni correttamente. Una nuova funzionalità che richiede un test è raramente costituita da un singolo componente, una funzione o un approccio e il suo impatto sul progetto potrebbe essere distribuito ampiamente e su scala diverse.

Le priorità di test potrebbero anche dipendere dalle esigenze della tua attività. I sistemi altamente tecnici potrebbero richiedere test delle unità complesse per confermare che un algoritmo univoco funzioni correttamente, mentre è probabile che gli strumenti altamente interattivi si concentrino su test visivi o test end-to-end per confermare che input touch complessi generano la risposta corretta.

Il tuo approccio ai test

Prova a concentrarti sui casi d'uso del codebase, indipendentemente dalla loro scala. Immagina in che modo l'utente potrebbe utilizzare qualsiasi parte del progetto, ad esempio un singolo componente, una funzione di livello inferiore o un caso d'uso end-to-end di alto livello. Ciò può anche rivelare carenze nelle tue astrazioni su qualsiasi scala, se scopri che il tuo test non riesce a interagire in modo ottimale con il codice in fase di test.

È importante che ogni scenario di test abbia un obiettivo ben definito. I test "catch-all" di grandi dimensioni possono essere complessi, proprio come nel codice non di test.

Un'occhiata allo sviluppo basato sui test

Lo sviluppo basato su test (TDD) è un approccio esclusivo ai test, di tipo ortogonale alla scalabilità, o di tipo, in quanto comporta la scrittura di test il cui esito è positivo, almeno all'inizio. Questo può essere valido sia per i test manuali che per quelli automatici: devi descrivere gli obiettivi da raggiungere, scoprire cosa manca nella soluzione o nel codice attuale e utilizzare il test con errori come guida per trovare una soluzione.

Naturalmente, non è utile testare tutti i possibili scenari in un'applicazione o un componente ipotetico ancor prima di iniziare a crearli. Il TDD ha il suo posto e può essere utile man mano che il codebase diventa più complesso.

Il TDD è una buona pratica anche per la correzione dei bug. Se puoi codificare il caso di riproduzione per un bug, puoi eseguire un test automatico che inizialmente non avrà esito positivo. Una volta corretto il bug, il test ha esito positivo, consentendoti di determinare se la correzione è riuscita senza conferma manuale.

Un diagramma di flusso per lo sviluppo basato su test.
Avvicinarsi al codice tenendo a mente uno sviluppo basato su test è una parte della filosofia del test
.

Riquadro opaco e trasparente

Si riferisce al modo in cui testi qualsiasi parte dell'impianto. Se è opaca, non è possibile vederne l'interno, ad esempio quando si utilizza l'interfaccia pubblica di una classe, invece di controllarne l'interno.

A meno che tu non abbia un motivo specifico per non farlo, è meglio iniziare con il test delle caselle opache, in modo da poter progettare test basati su come vengono utilizzati i componenti, senza distrarti dal funzionamento dei componenti interni. Se ti affidi solo all'interfaccia "pubblica" di un percorso di codice (non necessariamente pubblica per gli utenti, ma forse anche per altre parti del codice), puoi eseguire il refactoring e migliorare il codice sapendo che il test rileverà eventuali modifiche.

Un modo per convertire il codice "clear box" in modo che sia più opaco è introdurre elementi configurabili come astrazioni per le dipendenze del codice o callback per osservare lo stato, invece che uno stato strettamente accoppiato ad altri sistemi. Questo rende il codice più disaccoppiato e ti consente di fornire versioni "test". In alternativa, puoi simulare dove il tuo codice interagisce con altri sistemi.

Risorse