1. Unit Test
If it ain't tested, it's broken - Bruce Eckel
Approfondimento e linee guida sulla
creazione di Unit Test nelle applicazioni
2. Agenda
o Definizione di UnitTest
o Perch竪 fare UnitTest
o Framework per Unit Test
o Esepio
o Dal esempio al mondo reale
o Implementazione Domain Model
o Dal mondo reale alla nostra realt
o Guide Line
o Build
o Code Coverage
o Obbiettivi
Settembre 2011Unit Test
2
3. Settembre 2011Unit Test
3
Unit Test
Uno Unit Test 竪 un test che verifica il corretto funzionamento di una
unit funzionale (ad esempio un metodo) del sistema.
Ripetibile
Automatico
Indipendente
Veloce
Unit Test non individua l'assenza di errori ma ne evidenza la presenza
4. Settembre 2011Unit Test
4
Perch辿 fare Unit Test?
Test come Verifica
Verifichiamo che il codice sia aderente ai requisiti.
Test come Confidenza
I requisiti non sono scolpiti nella roccia "Change Happens" quando
cambiano o quando facciamo refactoring ci segnalano eventuali
errori.
I test sui bug ci aiutano ad evitare i bug di regressione.
Test come Specifica
Ti aiuta a capire se le specifiche sono complete ragionando sui casi
limite e a colmarle quando mancano.
5. Settembre 2011Unit Test
5
Perch辿 fare Unit Test?
Test come Buon Design
Se 竪 difficile o impossibile testare una cosa vuol dire che il design
non 竪 buono. Probabilmente l'accoppiamento tra i componenti 竪 alto
o il componente ha pi湛 responsabilit di quelle che dovrebbe avere.
Test come Banco di Prova
Ti permette di verificare porzioni di codice difficili da debuggare
perch辿 inseriti in contesti complessi facendoti risparmiare tempo.
Test come Documentazione
Leggendo i test si ha una idea di come il componente possa essere
utilizzato.
6. Settembre 2011Unit Test
6
In pratica
Per fare test utilizzo un framework
- MsTest
- MbUnit
- NUnit
La maggior parte dei framework di test si basa sulle Asserzioni
Cosa posso Asserire:
- A partire da un determinato input avr嘆 un determinato output
- A partire da un input avr嘆 una determinata eccezione
- Una determinata istruzione verr richiamata
7. Settembre 2011Unit Test
7
MsTest
Framework di testing integrato in Visual Studio 2010.
Consente di creare Unit Test, Web Test, Load Test e CodedUi Test.
Le classi sono marcate con lattributo TestClass i metodi
con TestMethod e le asserzioni vengono fatte con la classe Assert.
ClassInitialize ClassCleanup vengono chiamati rispettivamente
allinizio e alla fine dellesecuzione di test in una classe e
TestInitialize TestCleanup prima e dopo lesecuzione di un
metodo.
8. Settembre 2011Unit Test
8
Il mio primo Test
Requisiti
Il conto corrente ha un saldo che riporta il denaro attualmente
depositato.
Sul conto corrente posso prelevare o depositare denaro.
Non posso prelevare pi湛 di quello che ho sul conto.
Quando il conto corrente viene creato il saldo 竪 0.
9. Settembre 2011Unit Test
9
Dal primo test -> al Mondo Reale
Quando passiamo da un esempio al mondo reale quello che succede
竪 che la complessit aumenta.
Ci accorgiamo quindi che dobbiamo testare molte cose e testare
alcune di queste diventa difficile.
Design for testability
Progettare bene una applicazione significa pi湛 facilit nello
scrittura dei test.
Principi (Basso Accoppiamento, Alta Coesione, SOLID, ecc)
Pattern (Domain Model, Inversion of control, ecc)
Priorit nei test
I test hanno un costo
Devo testare prima le parti pi湛 critiche e pi湛 importanti
10. Settembre 2011Unit Test
10
Dal Mondo Reale -> alla nostra realt
Prima di vedere i test applicati sulle nostre applicazioni abbiamo
bisogno di aprire una parentesi parlando di come 竪 cambiato il modo
di implementare il pattern Domain Model.
Requisiti
Quando un cliente viene messo in black list bisogna indicarne il
motivo e congelare tutti gli ordini.
12. Settembre 2011Unit Test
12
Domain Model
An object model of the domain that incorporates both behaviour and data.
POEAA Martin Fowler
Insieme di classi correlate tra loro in un grafo che rappresentano il dominio di
nostro interesse, ordini di vendita, tubi, farmaci, spedizioni
Focalizzando lattenzione su
Dati (propriet)
Comportamento (metodi)
14. Settembre 2011Unit Test
14
Guide Line - Cosa
Cosa dobbiamo testare?
Nella maggior parte della applicazioni che stiamo realizzano abbiamo
scelto di utilizzare il Domain Model.
Il DOMINIO 竪 quindi la parte del nostro software che:
Contiene tutta la logica di Business
la parte pi湛 facile da testare
Cosa non va testato?
Teoricamente niente ma in realt
Propriet vuote
Dto non hanno comportamento
15. Settembre 2011Unit Test
15
Guide Line - Come
Come dobbiamo testare?
Test brevi
Alta leggibilit
Se fallisce il test devo capire subito il motivo
Manutenibilit
Testare una cosa sola
I test devono essere
Ripetibile
Automatico
Indipendente
Veloce
16. Settembre 2011Unit Test
16
Guide Line - Quando
Quando fare Test?
Durante lo sviluppo della funzionalit stessa
Come gestire i costi
Prima di iniziare a fare test il Gestore di Progetto e il Responsabile
Tecnico devono esserne a conoscenza.
Aver creato da subito una buona architettura consente di avere
costi sulla creazione dei test inferiori.
17. Settembre 2011Unit Test
17
Guide Line - Naming
Quali Naming Guideline ci sono?
Nome di progetto Progetto.Test
Nome delle calssi ClasseTest
Nome del metodo da testare
Metodo_ Scenario _ RisultatoAtteso
I test sullo stesso metodo sono raggruppati in region
18. Settembre 2011Unit Test
18
Domain scenario
Uno scenario di test 竪 unistanza del dominio che rappresenta il
maggior numero possibile degli stati (scenari) che le singole entit
possono assumere.
Quando
Il dominio 竪 complesso e le entit sono strettamente connesse.
Perch辿
Scrivere test pi湛 velocemente
Rendere i test pi湛 leggibili
Come
Lo scenario ideale deve essere credibile, complesso, e facile da
usare.
19. Settembre 2011Unit Test
19
Build
La build 竪 lindicatore di salute del progetto
Lesecuzione dei test viene automatizzata nellambiente di Build
tramite un processo di Continus Integration.
Quando una build si rompe tutto il team deve concentrarsi sul
risolvere il problema.
Risulta importante che siano state rispettate le caratteristiche di test:
Ripetibile
Automatico
Veloce
20. Settembre 2011Unit Test
20
Code coverage
Il code coverage 竪 la misura che descrive la percentuale del codice
sorgente che 竪 stato testato in un programma.
un indicatore e quindi va contestualizzato e interpretato ma
fornisce una buona indicazione.
In MsTest vengono conteggiate le righe che vengono eseguite
durante lesecuzione dei test.
21. Code coverage
Possiamo vedere le linee non coperte dai test
Il code coverage viene analizzato durante lesecuzione della build.
Settembre 2011Unit Test
21
23. Settembre 2011Unit Test
23
Obbiettivi
In Pico nei prossimi giorni verr inserito il documento con gli
Obbiettivi di code coverage da raggiungere per ogni progetto.
#4: Ripetibile
- Deve essere possibile ripeterlo tutte le volete che si vuole
Automatico
- Eseguibile non da un utente
Indipendente
- Deve essere indipendente da altri test e indipendente da fattori esterni
Veloce
Una volta fatti i test non saremo sicuri che la nostra applicazione funziona ma avremo pi湛 confidenza
#6: Banco di prova
Devo fare F5, aspettare che compili, raggiungere la pagina (magari creare ordini, ecc) ed eseguire lazione
#7: Esempio della somma 1+2 = 3
Esempio della divisione (1/0) = Exception
#8: Finestre di Visual Studio
Test View
Vedo lelenco di tutti i testPosso eseguirne uno o pi湛 sia in debug che non
Test Result
Vedo il risultato dei test con il motivo delleventuale fallimento del test
#9: Nel test mancano le verifiche sul passaggio di valori positivi e negativi
public class ContoCorrente
{
public ContoCorrente()
{
Saldo = 0;
}
public double Saldo { get; private set; }
public void Deposita(double denaro)
{
Saldo += denaro;
}
public void Prelieva(double denaro)
{
if (denaro > Saldo)
throw new InvalidOperationException("saldo superato");
Saldo -= denaro;
}
}
--------------
[TestClass()]
public class ContoCorrenteTest
{
[TestMethod()]
public void ContoCorrente_Creazione_Saldo0()
{
ContoCorrente target = new ContoCorrente();
Assert.AreEqual(0, target.Saldo);
}
[TestMethod()]
public void Deposita_Saldo0_VerificaSaldo()
{
ContoCorrente target = new ContoCorrente();
double denaro = 10.5;
target.Deposita(denaro);
Assert.AreEqual(10.5, target.Saldo);
}
[TestMethod()]
public void Prelieva_SaldoPositivo_VerificaSaldo()
{
ContoCorrente target = new ContoCorrente();
double importoDepositato = 5;
double importoPrelevato = 3;
target.Deposita(importoDepositato);
target.Prelieva(importoPrelevato);
Assert.AreEqual(target.Saldo, importoDepositato - importoPrelevato);
}
[TestMethod()]
[ExpectedException(typeof(InvalidOperationException))]
public void Prelieva_Saldo0_Eccezione()
{
ContoCorrente target = new ContoCorrente();
double denaro = 5;
target.Prelieva(denaro);
}
}
#10: Eric brec - Product Manger
Qualit non in dubbio - la sfida 竪 la velocit l'accuratezza e la sostenibilit
#11: Adesso vediamo come si applicano i test sui nostri progetti ma prima
#12: Sotto il nome di Domain Model Anemico ci finisce una serie di modi di interpretare
Non sappiamo come il customer 竪 stato cambiato fuori dalla business logic
Ci scontriamo con gestire la persistenza
Non stiamo sfruttando il grafo
#14: I metodi di manager prendono in ingresso campi o dto non entit
Il dominio non si occupa della persistenza
Esprimere lintero grafo
Aggregate root
Proteggere il dominio
Metodi per la costruzione di oggetti
Rimuovere i setter non necessari
#19: Perch辿 portare un soggetto in uno stato potrebbe essere tedioso