Rispondere alla domanda "quanti unit test è necessario scrivere?" non è semplice e non esiste una risposta univoca, ma è necessario comunque possedere qualche cifra per capire se stiamo testando: nulla, poco, abbastanza o tutto.
La metrica più interessante in questo il Code Coverage ,la percentuale di linee di codice del progetto che sono state eseguite dai test dopo un'esecuzione.
Sebbene alcune scuole di pensiero sostengano che il 100% di code coverage sia sufficiente ad individuare tutti i bug, senza scatenare guerre ideologiche si può comunque affermare che se si ha un code coverage del 10%, sicuramente ci troviamo nella situazione di Unit Testing scarso o nullo.
Il Code Coverage è quindi molto probabilmente la metrica più importante che si può estrarre dall'esecuzione degli Unit Test e Visual Studio la supporta nativamente. Per abilitare questa opzione è necessario aprire il file con estensione testsettings
, dove sono memorizzate tutte le opzioni relative all'esecuzione dei test.
Come si può vedere nella solution di esempio ci sono due file con questa estensione, chiamati rispettivamente TraceAndTestImpact.testsettings
e Local.testsettings
. Avere più configurazioni di test è necessario perché alcune metriche, come appunto il del Code Coverage, richiedono una maggiore capacità di calcolo e quindi rallentano l'esecuzione dei test.
Grazie alla possibilità di avere più configurazioni, l'approccio consigliato è appunto quello di generare più configurazioni differenti e scegliere quella da usare con il menu Test > Select Active Test Settings
. Per questa ragione Visual Studio crea automaticamente due configurazioni di base, ma è possibile comunque aggiungerne di altre semplicemente premendo il tasto destro sulla solution e scegliendo la voce di menu New > File
, aprire la finestra di creazione nuovo file e scegliere Test Settings
.
L'opzione per abilitare il Code Coverage si trova nella sezione Data And Diagnostics
, dove sono rappresentate tutte le categorie di dati che Visual Studio è in grado di "catturare" durante l'esecuzione dei test. Alcune di queste categorie non sono veri e propri dati, come il Network Emulation che ha lo scopo simulare una rete lenta durante l'esecuzione del test.
Nella Figura 12 è evidenziato il tasto Configure che serve per configurare la categoria scelta. Nel caso del Code Coverage è fondamentale eseguire la configurazione, selezionando gli assembly su cui vogliamo collezionare i dati. Questa opzione è necessaria per due motivi:
- solitamente non si vuole conoscere il Code Coverage per tutti gli assembly, ma solamente per quelli che sono sotto test
- per raccogliere i dati di Coverage nel modo più preciso possibile, gli assembly vengono "Instrumentati": viene inserito del codice apposito per effettuarne il monitoraggio, rallentando quindi l'esecuzione dei test
Nel nostro esempio è sufficiente scegliere l'assembly MyMath
ed eseguire nuovamente tutti i test.
Al termine dell'esecuzione, nella finestra Test Results
, è possibile premere l'ultimo bottone a destra (fate attenzione perché spesso non è visibile a causa della lunghezza della toolbar e bisogna cliccare l'ultimo tasto che permette di vedere i bottoni che non entrano nella toolbar) che permette di visualizzare i dati di Code Coverage.
In questo caso il risultato mostra che i test eseguono tutto il codice della classe sotto test, ma l'aspetto importante è che si è in grado di vedere la percentuale divisa per classi, namespace ed assembly.
Modificando il metodo Divide
aggiungendo alcune righe di test che verificano che il divisore sia diverso da zero e rieseguendo i test si può notare che la percentuale di code coverage diminuisce, ma l'aspetto più importante è che, effettuando doppio click dalla finestra del Code Coverage, viene aperto il sorgente con l'evidenziazione delle righe chiamate e non, come mostrato nella figura seguente:
In questo modo è possibile visualizzare in maniera chiara i punti del codice che non sono stati mai eseguiti durante i test e che costituiscono logica non testata.