Testing

Embed Size (px)

Citation preview

  • 1. Testing Test Driver Development Design Improvement alias Refactoring Continuous Integratione altre pratiche Domenico Briganti 14/06/2006

2. Agenda

  • Test Driven Development
  • Test Unitari con JUnit
  • MockObject
  • Refactoring
  • Continuos Integration
  • Vari ed eventuali

3. Domanda...

  • Chi scrive dei test per il proprio codice?
  • Bene....perch?

4. I problemi durante lo sviluppo...

  • Tempo di realizzazione
  • 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
    • Rifattorizzare spesso

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
  • Per testare tu devi:
    • realizzare molti oggetti
    • che fanno poche cose

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:
    • Prestazioni
    • Memoria consumata
    • Stile e comprensione
  • 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:
  • Sono sufficienti
  • 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
  • Ma soprattutto:
  • 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
  • Scrivi prima il test!
  • 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...
  • ma...
    • 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
  • Test del design
  • 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:
    • Unit testing
      • Testare ununit di codice, tipicamente un metodo/classe
    • Integration testing
      • Testare un modulo (es. Un package)
    • Application testing
      • Testare il codice dal punto di viste dellutente (black box)

20. JUnit, the java testing framework

  • Scritto daErich Gamma and Kent Beck
  • Open Source
  • 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 deriva da TestCase
  • 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:
    • @BeforeClass
    • @AfterClass
    • @Before
    • @After
  • 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 :
    • assertNotNull
    • assertEquals
    • assertTrue, assertFalse
    • assertSame, assertNotSame
    • ecc. ecc. ecc.
  • 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....."));
  • return suite;
  • }
  • }

28. Unit Best Practices 4/4

  • Non caricare le risorse dal file system con percorsi hard-coded:
  • public void setUp () {
  • FileInputStream inp ("C:TestDatadataSet1.dat");
  • ...
  • public void setUp () {
  • FileInputStream inp ("dataSet1.dat");
  • ..
  • public void setUp () {
  • InputStream inp = SourceResourceLoader.getResourceAsStream (this.getClass (), "dataSet1.dat");

29. DEMO

  • Test JUnit 3.8.1
  • Test JUnit 4

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

  • Unit tests failed.

35. Report del test 36. DEMO

  • Test JUnit 3.8.1 con ANT

37. Tutto bello...ma...

  • Come testate un test che coinvolge una risorsa esterna?
  • Come testare eventi?
  • Come testare eccezioni?
  • Come verificare iterazioni complesse?
  • Come testare Servelt e EJB?
  • Come testare un plugin per Eclipse?
  • Come testare

38. Mock Object

  • E' un oggetto finto che si comporta come l'originale
  • pi veloce
  • 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");
  • EasyMock.replay(a);
  • reg.addAnimale(a);

41. DEMO

  • Test Mock Object
  • Test LocalDbExplorer

42. Atri tool xUnit

  • SUnit (Per SmallTalk, considerato il padre di tutti gli unit test framework)
  • CppUnit
  • XMLUnit
  • DbUnit
  • NUnit
  • PyUnit
  • RubyUnit
  • ...

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 .
  • Martin Flower

44. C.I.: punti salienti

  • Build ad ogni commit
  • 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

  • Test LocalDbExplorer
  • con ANT e CruiseControl

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
  • http://www.mokabyte.it
  • 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.javaworld.com
  • http://www.wikipedia.org/

52. Riferimenti 2/2

  • Cos XP http://www.xprogramming.com/xpmag/whatisxp.htm
  • http://www.pairprogramming.com

53.