Home Page Home Page Articoli Utilizzare NUnit per testare codice .NET

Utilizzare NUnit per testare codice .NET

Scopriamo in questo articolo come utilizzare il popolare framework Open Source NUnit per effettuare Unit Testing del codice .NET aumentandone la qualità e riducendo il numero di eventuali bugs.
Autore: Michela Zangarelli Livello:

Cosa fa e a cosa serve NUnit?


NUnit è un framework deputato alla creazione di classi di test.Sono molte le cose che si possono fare con questo framework ma qui ci occuperemo del sistema di test più semplice, ovvero, data una classe, si creano dei test sui metodi di questa classe indicando cosa è atteso in output. Questi test vengono poi eseguiti e si confronta il risultato ottenuto dall'elaborazione con quello atteso e si può rapidamente verificare se l'unità di codice (Unit) funziona correttamente.

Perché dovrei usarlo?


Può sembrare una cosa tanto semplice da risultare inutile, e forse lo è per applicazioni elementari o di piccole dimensioni; ma chiunque abbia passato giorni e giorni a testare un'applicazione di elevata complessità dopo l'implementazione di una nuova release sa bene quale differenza può fare...

Che vantaggio mi può dare NUnit in una applicazione semplice ?


Diciamo innanzitutto che i test automatizzati non possono sostituire in toto quelli manuali infatti le fasi di testing si dividono in Automatic Testing e Manual Testing. Il punto è che i test eseguiti a mano dagli utenti dovrebbero limitarsi a fornire informazioni sull'usabilità, sull'interfaccia e sulla possibilità di commettere errori dovuti al fattore umano (doppio click su un tasto di submit di una web application, interfaccia poco intuitiva e conseguente confusione sulle funzionalità, inserimento di dati errati...).

Ai test automatici dovrebbe essere riservato il ruolo di garantire il corretto funzionamento del motore dell'applicazione, ossia dato un corretto input, indipendentemente da come qualsiasi funzione sia stata implementata o da qualunque refactoring vi sia stato apportato, devo ottenere un corretto output.

I vantaggi di questo approccio sono: maggiore velocità, codice scritto meglio (in alcune aziende vige la prassi di versionare il lavoro della giornata solo se i test hanno dato esito positivo), maggiore affidabilità (l'utente umano può sbagliare nel valutare un risultato, il risultato stesso può essere influenzato tanto da un errore nel codice quanto da un errore umano nell'uso dell'applicazione), solo per menzionare i più immediati.


Come installare NUnit sulla macchina di sviluppo


L'installazione di NUnit è semplicissima, basta scaricare il pacchetto dall'area Download del sito web (NUnit Download ), scegliendo il pacchetto autoinstallante con estensione MSI per il framework che si vuole utilizzare.

Per esempio, per lavorare col .NET Framework 2.0 bisognerà scegliere la riga indicante "win .net 2.0", ossia il link al file "NUnit-2.4.8-net-2.0.msi" (la versione attuale è la 2.4.8) e il download parte in automatico.



Le indicazioni per l'installazione, per chi volesse leggerle, sono fornite passo passo in questa pagina (in inglese):
NUnit Installation 

Tuttavia l'installazione del framework non presenta davvero alcuna complicazione, facendo doppio click sul file appena scaricato si avvierà una procedura automatica che presenterà la licenza d'uso e chiederà dove salvare i file.

La licenza garantisce a ciascuno di poter usare il programma senza limitazioni, con le sole condizioni di indicare chiaramente se si distribuiscono versioni modificate, che di tali si tratta e non dell'originale.



Si può benissimo lasciare il percorso standard: saranno create le icone sul desktop e nel menu avvio, e in pochi secondi sarà tutto pronto.

Ora che NUnit è stato installato si può testare, caricando l'apposita classe di test fornita con l'installazione stessa.

Dal menu File scegliere Open Project: indicare il percorso di installazione di NUnit, da lì selezionare la cartella Bin, e in essa il file NUnitTest.NUnit



Una volta caricato il file, è sufficiente premere il tasto Run per far partire il test.



Ecco come appare un test in cui tutti gli elementi hanno dato un risultato positivo:



Come creare una classe di test con il framework NUnit


La cosa più semplice è creare la classe di test all'interno del progetto stesso da testare.

Si potrebbe anche creare un progetto a parte per i test: in questo caso occorrerebbe semplicemente aggiungere il riferimento all'assembly che deve essere testato. Io personalmente ho trovato più pratico il primo approccio, cioè nello stesso progetto creo la classe e il suo test, anche se forse a lungo andare può creare progetti "disordinati".

Supponiamo comunque di usare questo sistema, di creare cioè la classe di test nello stesso progetto della classe funzionale.

Per prima cosa occorre aggiungere ai riferimenti del progetto quello dell'assembly di NUnit:



poi si crea la classe di test.

Per iniziare io ho creato appositamente una classe funzionale chiamata "Calcolatrice" che implementa le cinque operazioni di somma, sottrazione, divisione, moltiplicazione e modulo, esponendo cinque metodi che richiedono in input (ovviamente) due numeri Double e restituiscono un Double come risultato.

Per eseguire i test su Calcolatrice occorre creare una classe che chiamerò, per esempio, testCalcolatrice.vb.

Innanzitutto è necessario che questa classe importi il namespace di NUnit:



Poi è indispensabile che la classe sia marcata come classe di test con l'attributo <TestFixture()>, così come in figura:



Vediamo quali sono gli elementi significativi della nostra classe di test:



1) La sub di setup. È la prima che viene eseguita, ed è riconosciuta come tale dall'attributo : il nome è assolutamente indifferente, l'ho chiamata Init() ma avrebbe potuto essere Inizio() o qualsiasi altra cosa.
Si usa per inizializzare gli elementi del test: in questo esempio istanzio la classe da testare e valorizzo le sue proprietà (i numeri su cui eseguire i calcoli) con 10 e 8.

2) La sub conclusiva. Anche questa viene identificata dall'attributo <TearDown()>, e il nome che scegliamo nell'ambito dell'applicazione è indifferente.
E' l'ultima che viene eseguita: si usa per compiere le operazioni finali del test, nel caso di esempio infatti cancello l'oggetto istanziato.

3) Le varie classi di test
Queste classi, riconosciute dall'attributo <Test()>, sono quelle che vengono eseguite in sequenza e il cui risultato sarà indicato come un successo o un fallimento in base al confronto fra la condizione attesa e la condizione risultante alla fine.

Come si definisce un test?


Un test si definisce innanzitutto creando una subroutine marcata come <Test()>, come abbiamo appena visto.
Al suo interno devono essere eseguite tutte le operazioni da testare: la cosa fondamentale è che questa routine contenga l'indicazione del risultato atteso come condizione di riuscita.



Queste indicazioni vengono inserite con gli statement Assert, come indicato nell'immagine.
Questi statement consentono una flessibilità molto alta rispetto al risultato atteso: è possibile controllare l'eguaglianza, l'identità, un valore booleano, una stringa contenuta in un'altra, e così via fino a controlli più complessi.

Nell'esempio indicato viene controllata l'eguaglianza fra due numeri, cioè lo statement Assert è così formato:

Assert.AreEqual(ValoreAtteso, ValoreRestituito)

Per una panoramica sugli Assert, si veda questo link:
NUnit Assertions 

Comunque l'installazione di NUnit ha con sé una guida locale molto completa, che contiene una reference complessiva degli Assert.

Ho scritto il test: ora come lo eseguo ?


Una volta scritta la classe di test, occorre innanzitutto compilarla.
Chi sviluppa con Visual Studio .NET lo fa dal menu Genera/Build, come per tutte le altre classi:



Fatto questo, è il momento di eseguire il test.

Apriamo NUnit, e come abbiamo fatto dopo l'installazione, carichiamo il nostro progetto.

Dal menu File scegliamo Open Project e seguiamo il percorso della nostra applicazione, individuando la cartella \bin, poi (in base a com'è stata generata la classe) Debug o Release.



Qui si carica l'exe generato dal compilatore, e in automatico avremo a disposizione la serie di test che abbiamo generato nella nostra classe:



Possiamo eseguirli tutti, oppure uno solo, selezionandolo e scegliendo Run.
Come si vede, questi test danno tutti un risultato positivo, ovvero tutti i metodi hanno restituito il valore atteso.



Ora modifichiamo il codice del test della sottrazione così da generare un test fallito: anziché

Assert.AreEqual(2, prcCalcolatrice.Risultato)

come condizione indichiamo:

Assert.AreEqual(4, prcCalcolatrice.Risultato)

N.B. non è necessario tutte le volte eseguire la load del progetto modificato: appena compilata la classe con le modifiche, NUnit provvede da solo al reloading con la versione aggiornata.

Essendo i due valori 10 e 8, il test ovviamente fallirà per la sottrazione, e la situazione sarà questa:



Come si vede, uno dei test è fallito.

Per avere dettagli sui valori coinvolti basta cliccare, in basso, sul Tab "Errors and Failures" per mostrare un riassunto dei valori attesi e di quelli risultanti dall'esecuzione:



Link Utili


NUnit Home Page 
Marco Turrini NUnit 
.NET Architects NUnit 
Voto medio articolo: 4.0 Numero Voti: 1
Michela Zangarelli

Michela Zangarelli

Programmatrice per passione e per gioco dai quattordici anni (con GW-Basic in ambiente MS-DOS): non mi ha mai abbandonato la sensazione che il mio lavoro sia un gioco, bellissimo, difficile e divertente. Come lavoro ho iniziato con il COBOL nel 2001, sono seguiti VB 6.0 e Asp 3.0. Attualmente sono analista programmat... Profilo completo

Articoli collegati

SQL Injection, che cosa è e come difendersi
I malintenzionati sono sempre dietro l'angolo. Il SQL Injection è una delle pratiche più semplici da utilizzare per attaccare un'applicazione poco sicura e violarla o arrecare danni al database. Vediamo che cos'è e come garantire la sicurezza delle applicazioni in modo adeguato.
Autore: Alessandro Alpi | Difficoltà: | Commenti: 4
Visual Studio 2005 Team System
Scopriamo il nuovo IDE di sviluppo che copre interamente l'intero ciclo di vita del software integrando in un solo ambiente più prodotti e studiato apposta per i ruoli di Architect, Developer e Tester.
Autore: Marco Caruso | Difficoltà: | Voto:
Tutorial ADO.NET ed esempi pratici - Parte 2
Dopo aver fatto un po' di teoria su ADO.NET nella Parte 1 dell'articolo procediamo con un Tutorial pratico che ci condurrà alla creazione di un'applicazione basilare che consenta l'accesso e la modifica dei dati su un Database Access.
Autore: Stefano Passatordi | Difficoltà: | Commenti: 10
Introduzione ad ADO.NET - Parte 1
ADO.NET è uno dei componenti chiave del .NET Framework. Eredita il nome dal vecchio ADO ma è praticamente quasi tutto cambiato. Una nuova architettura, nuovi concetti, nuove funzionalità e nuovi oggetti. Vediamo quali sono e a cosa servono.
Autore: Stefano Passatordi | Difficoltà: | Commenti: 6
Colonne calcolate e parola "Child" con ADO.NET
Una cosa utile di ADO.NET e' la possibilita di aggiungere ad una colonna da codice il cui valore sia il risultato di operazioni sui dati dei record (o tra valori di altre colonne). Quando si utilizza un dataset con piu tabelle collegate mediante relazioni invece, usando la parola chiave "child" si possono avere delle informazioni riguardanti le tabelle figlio, direttamente nei record della tabella
Autore: Matteo Raumer | Difficoltà: | Voto:
Usare degli indicatori di progresso con Query SQL
Nell'articolo vediamo come sia possibile con un l'aiuto delle classi DataReader e Command di ADO.NET, mostrare un indicatore di progresso che indichi lo stato di avanzamento di una query SQL durante il fetching dei dati.
Autore: Matteo Raumer | Difficoltà: | Voto:
La crittografia e la classe Rijndael
Vediamo come utilizzare una delle tante classi messe a disposizione dal .NET Framework per la crittografia dei dati. In particolare la classe Rijndael implementa un algoritmo di crittografia molto forte diventato famoso negli ultimi anni.
Autore: David De Giacomi | Difficoltà:
DES il famoso standard creato da IBM per la crittografia dei dati
In questo articolo dimostreremo come crittografare dei file usando il .NET Framework e in particolare la classe DESCryptoServiceProvider che implementa l'ormai noto algoritmo di cifratura inventato da IBM negli anni 70 chiamato DES (Data Encryption Standard)
Autore: David De Giacomi | Difficoltà: | Commenti: 2 | Voto:
Cosa sono e come funzionano le funzioni ricorsive?
Ecco tre esempi efficaci che vi spiegano come usare correttamente le funzioni ricorsive, per effettuare ricerche di file e cartelle all'interno del disco fisso, per ricostruire la struttura di un file XML oppure per svuotare determinati controlli in una Form.
Autore: Matteo Raumer | Difficoltà: | Commenti: 2
Costruire Console Applications con Visual Studio .NET
Spiegheremo in questo articolo i passi base fondamentali per costruire Console Applications utilizzando Visual Studio .NET.
Autore: David De Giacomi | Difficoltà: | Voto:
TextReader e TextWriter
Una panoramica su come utilizzare queste due classi che ci permettono di leggere e scrivere file di testo.
Autore: David De Giacomi | Difficoltà: | Commenti: 1 | Voto:
Giochiamo un po' con il registro di Windows!
Scopriamo uno degli elementi fondamentali del sistema operativo Windows e vediamo come è possibile accedervi tramite le classi offerte dal .NET Framework: Microsoft.Win32.Registry e Microsoft.Win32.RegistryKey
Autore: David De Giacomi | Difficoltà: | Commenti: 1 | Voto:
.NET Framework 1.1 Beta
Una prima panormaica sulle novità offerte dal Framework 1.1 che sarà integrato nella prossima versione di Visual Studio .NET 2003.
Autore: David De Giacomi | Difficoltà:
Cosa posso costruire con Visual Studio .NET ?
Un' introduzione sui vari tipi di progetto disponibili in Visual Studio dalle tipiche applicazioni Windows fino alle recenti applicazioni Web e agli innovativi Web Services.
Autore: David De Giacomi | Difficoltà: | Commenti: 1
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5