- 1. Testing Test Driver Development Design Improvement alias
Refactoring Continuous Integratione altre pratiche Domenico
Briganti 14/06/2006
2. Agenda
3. Domanda...
- Chi scrive dei test per il proprio codice?
4. I problemi durante lo sviluppo...
- Non sappiamo come funziona (ma funziona!)
- Non si realizzano componenti riusabili
- Modifichi qui....e li spacca molto pi in l (accorgendotene dopo
un mese e con un giorno di debugger)
- Il codice regredisce e invecchia pi velocemente
- Il prodotto consegnato ha dei bug ( sempre )
- Ecc.ecc.ecc.ecc (tanti ecc.!!!!)
5. Come migliorare la situazione?
- Usare TDD (non la soluzione di tutto!!)
-
- Non scrivere codice senza che esista un test AUTOMATICO che
fallisce
-
- Si mantiene una TODO list
-
- Sei costretto a pensare prima di scrivere un test...
-
- ...e a chiedere, subito, quando non capisci una
funzionalit
6. Altri vantaggi di TDD...
- Il tuo design migliora ed evolve continuamente
-
- si pensa al cosa e non al come
-
- ma solo nella direzione necessaria
-
- non c' nulla di superfluo
7. E ancora
- Usi il debugger sono quando necessario...
- ...e nel punto giusto (se i test sono sufficientemente
piccoli)
- Descrivi il codice nel modo pi rapido e aggiornato
possibile...
- ...indicando cosa vuoiottenere
- Meno commenti, meno documentazione!
- Libert di rifattorizzare senza provare rimorsi!
- basso accoppiamento fra gli oggetti e alta coesione
8. Due concetti: Alta coesione e basso accoppiamento
- Importati indici per indicare la qualit del codice
- Coesione: fa riferimento al numero e alla eterogeneit dei
compiti di cui una singola unit responsabile (classe o metodo); Se
ciascuna unit responsabile di un singolo compito, diciamo che tale
unit ha unaalta coesione
- Accoppiamento: Laccoppiamento si riferisce ai legami tra unit
separate di un programma; Se due classi dipendono strettamente per
molti dettagli luna dallaltra, diciamo che sonostrettamente
accoppiate
9. Cos ilRefactoring(Design Improvement)
- Rifattorizzare indica la procedura che porta a migliorare il
codice in termini di:
- Senza di fatto modificare il comportamento
vistodall'esterno.
- Si fa perch col passare del tempo la manutenzione del codice e
laggiunta di nuove funzionalit provocano la perdita di coesione e
aumentano laccoppiamento
- Porta a eliminare le duplicazioni nel codice (segno di scarso
design)
10. NON Regressione...
- Si rifattorizza spesso, e il pericolo di inserire bug
alto.
- Le suite di test ti proteggono dalla regressione
- I bug non riappaiono all'improvviso (wow!)
- Il tuo sistema funziona con continuit
11. Ma...quando testare?
- Quando pensiamo ai test, spesso ci chiediamo:
- Quale logica o dato testare
Risposte???? 12. Creare nuovi test:quando
- Si aggiunge una nuova feature
- Si ha un bug (regression test)
- Si deve capire come funziona qualcosa (learging test)
- Per spiegare il funzionamento di qualcosa
- I test devono essere scritti prima del codice da testare, non
lo testerete mai dopo!!
13. Come scriverli
- Prima diiniziare , fate una lista di tutti i test chedovrete
scrivere :
-
-
- Consente di tenere traccia di cosa dobbiamo fare
-
-
- Permette di concentrarci su una cosa alla volta
-
-
- Possiamo tenere sotto controllo l'avanzamento
- Scegliete i dati senza spararli a caso, il test fa
dadocumentazione
- Isolandoli e che garantiscano la localit degli errori
- Rendi chiara la relazione tra dati di ingresso e diuscita
.
- separati dal codice applicativo (es. crearli in package
diversi)
14. Ottimizzare i test...
- Se far funzionare il test richiede troppo tempo, spezzarlo in
pi parti
- Se i test usano una risorsa difficile da usare, crea un Mock
Object
- Se lavori in team lascia sempre i test funzionanti altrimenti
barre rosse!
- Se un test fallisce, devi avere un problema: se due test
falliscono devi avere due problemi...
- I test devono essere indipendenti dall'ordine in cui si
lanciano.
15. Ne vale la pena?
- Il testing porta via met del tempo dello sviluppo...
-
- Il tempo totale di sviluppo diminuisce
-
- Il tempo di debugging diminuisce drasticamente
-
-
- Quando scavi col debugger nel codice non sai se finirai tra 1
minuto o tra 2 giorni (perch poi ti arrendi!)
-
-
- Il costo di debugging ritenuto di gran lunga la componente
principale nella formazione del costo dei moderni progetti di
software
16. Costo di un bug e localit Fonte:
http://www.dia.uniroma3.it/~merialdo/didattica/aa2005-2006/poo/trasparenze/POO-17-testing-tecniche.ppt
17. Quindi...
- Se ben progettati e mantenuti, i test aiutano a confinare i bug
nella zona verde , ovvero con forti caratteristiche di
localit:
-
- i bug hanno caratteristiche tali da manifestarsi immediatamente
e palesemente
-
- il difetto nel codice ricercabile in un numero di linee non
eccessivamente elevato e comunque ben identificabili
- Le esecuzioni che manifestano il bug non sono mai troppo lunghe
e/o troppe complesse
-
- in particolare non devono esserlo dal momento in cui lerrore si
verifica a quello in cui si manifesta
18. Testing e fasi di sviluppo
- Il testing NON una fase dello sviluppo; va previsto in tutte le
fasi, con significato e modalit diverse
- Ripetizione dei test precedenti quando si localizzano e
rimuovono difetti
Maintenance
- Controllo di coerenza progetto/implementazione
- Esecuzione dei test sul prodotto
Coding
- Controllo di coerenza progetto/requisiti
- Valutazione dellarchitettura di sistema
- Generazione di dati di test funzionali e strutturali
Design
- Generazione dei dati di test
- Determinazione della strategia di test
- Test dei requisiti e delle specifiche
Analysis Attivit di test Fase 19. Tipi di test
- Tantissime categorie, sommariamente:
-
-
- Testare ununit di codice, tipicamente un metodo/classe
-
-
- Testare un modulo (es. Un package)
-
-
- Testare il codice dal punto di viste dellutente (black
box)
20. JUnit, the java testing framework
- Scritto daErich Gamma and Kent Beck
- Dalla versione 4.0 fa anche uso delle annotazioni di Java
1.5
- Supporta asserzioni, suite test e report result
- Integrato in tantissimi IDE e tool di build (ANT, Maven,
CruiseControlquasi tutti)
21. JUnit Framework http://junit.sourceforge.net 22. Creare test
con JUnit < 4.0
- Si possono sovrascrivere i metodi setUp() e tearDown() che
vengono richiamati ad ogni esecuzione di test
- Si pu utilizzare il costruttore della classe per istanziare
oggetti usati da pi test (ed eventualmente sovrascrivere
finalize)
- Si definiscono uno o pi test con testXXX()
setUp() testXXX() tearDown() 23. Creare test con JUnit 4.X
- Si importa junit.framework.Assert che fornisce tutti i metodi
statici per gli assert
- Si annotano I metodi richiamati allo prima e dopo la
classe/test con:
- Si definiscono uno o pi test annotati con @Test
24. I metodi assert / fail
- Servono a verificare determinate condizioni (assert) o a
segnalare un esito negativo(fail)
- Esistono di diversi tipi assert :
-
- assertSame, assertNotSame
- Ognunodegliassert/fail con svariati tipi di parametri di input
(Stringe, numeri, oggetti...)
- Ilprimo parametro quello atteso, il secondo quello ottenuto dal
test delloggetto .
25. Unit Best Practices 1/4
- Separare il codice di test da quello da testare con cartelle
sorgenti diverse
- Compilarli insieme, questo comporta la loro sincronizzazione
durante lo sviluppo
- Anche per i test sono disponibili le tecniche dei linguaggi OO
(subclassing, helper, ecc.ecc.)
- Se la classe sotto test si chiamaXXX , allora gli si associa
una classe di test chiamataXXXTest (o xxxTestCase)nello stesso
package
26. Unit Best Practices 2/4
- I test devono essere indipendenti dal tempo
- Indipendenti dalle impostazioni di locazioni/nazionalit,
es.:
-
- Date date = DateFormat.getInstance ().parse
("dd/mm/yyyy");
-
- Calendar cal = Calendar.getInstance ();
-
- Cal.set (yyyy, mm-1, dd);
-
- Date date = Calendar.getTime ();
- Descriverli attraverso javadoc
27. Unit Best Practices 3/4
- Non assumere un ordine preciso per lesecuzione dei test, ma se
necessario creare una TestSuite inserendo nellordine i metodi di
test:
- public class TestSuiteConOrdine extends
junit.framework.TestSuite {
- public static junit.framework.Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(new RegioniTest("testConMock1....."));
- suite.addTest(new RegioniTest("testConMock2....."));
28. Unit Best Practices 4/4
- Non caricare le risorse dal file system con percorsi
hard-coded:
- FileInputStream inp ("C:TestDatadataSet1.dat");
- FileInputStream inp ("dataSet1.dat");
- InputStream inp = SourceResourceLoader.getResourceAsStream
(this.getClass (), "dataSet1.dat");
29. DEMO
30. Ant & JUnit Best Practices
- Usareper richiamare lesecuzione dei test
- Usare, errorpropertyefailurepropertyper notificare un evento di
errore/failure nei test
- Evitare di utilizzarehaltonfailute
- Usareper visualizzare il risultato del test
- Passaggio di parametri usando
- Usarein concomitanza con Continuous Integration
31. Passaggio di parametri al tests private String docsDir
=System.getProperty("docs.dir"); private String indexDir
=System.getProperty("index.dir"); 32. TestRunners con swing
(SwingUI) 33. Avviare il test con ANT
34. Report del test
35. Report del test 36. DEMO
37. Tutto bello...ma...
- Come testate un test che coinvolge una risorsa esterna?
- Come verificare iterazioni complesse?
- Come testare Servelt e EJB?
- Come testare un plugin per Eclipse?
38. Mock Object
- E' un oggetto finto che si comporta come l'originale
- Esistono vari tools che ne facilitano la creazione
- Aiutano a disaccoppiare le logiche
39. EasyMock
- Libreria OpenSource per creare MockObject a runtime
- Necessita di Java5 (solo per le versioni > 2)
- Crea Mock a partire da Interfacce (c unestensione che permette
di utilizzare anche classi invece di interfacce)
- Verifica opzionalmente lordine di chiamata dei metodi e il
numero di volte che vengono chiamati (anche tra mock object
diversi)
40. Usare EasyMock
- Regioni reg = new Regioni();
- Animale a = EasyMock.createMock(Animale.class);
-
EasyMock.expect(a.getLocazioneGeografica()).andReturn("Europa");
41. DEMO
42. Atri tool xUnit
- SUnit (Per SmallTalk, considerato il padre di tutti gli unit
test framework)
43. Continuous integration
- I s a software development practice where members of a team
integrate their work frequently, at least daily - leading to
multiple integrations per day. Each integration is verified by an
automated build (including test) to detect integration errors as
quickly as possible. Many teams find that this approach leads to
significantly reduced integration problems and allows a team to
develop cohesive software more rapidly .
44. C.I.: punti salienti
- Test automatici eseguiti ad ogni commit
- Build veloci e incrementali attraverso la verifica del log del
CVS/SVN
- Tutti possono vedere cosa accade nel processo di build
- Minimizza la probabilit di errori nella fase di
integrazione
45. Ciclo di build di C.I. VCS Build Artifacts Dir
Mail/Sound/Light 1. Bootstrap 2. Check for modifications 3. Get the
revision log Cruise Control Your projectsBuild file Ant, Maven,
Make 2. Run Build 5. Publish Artifacts 6. Sendto publisher 1. Get
the latestsource 3. Tag source(optional) Project Specific Adapter -
Ant Script 4. Run Build 46. CruiseControl
- http://cruisecontrol.sourceforge.net/
- Interfaccia Web per monitorare il processo di build
- Si integra con ANT, CVS e altri sistemi di source control
- Notifica con email a responsabili di progetto e di modulo se
una compilazione/test fallisce
47. Come funziona CruiseControl 48. DEMO
49. Conclusioni
- Any program feature without an automated test simply doesnt
exist. from Extreme Programming Explained, Kent Beck
50. Di cosa abbiamo parlato... 51. Riferimenti 1/2
- Le slides di Bruno Bossola (JugTorino) al webbit 03:
http://www.jugtorino.it/vqwiki/jsp/Wiki?LeSlideDelWebbit
- Ingegneria del Software Maurizio Pizzonia
http://www.dia.uniroma3.it/~pizzonia/swe/
- Ingegneria del Software Paolo Merialdo
- http://www.dia.uniroma3.it/~merialdo
- http://www.martinfowler.com
- http://www.wikipedia.org/
52. Riferimenti 2/2
- Cos XP http://www.xprogramming.com/xpmag/whatisxp.htm
- http://www.pairprogramming.com
53.