SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
Dominare il codice
   ereditato
  Tommaso Torti e Matteo Vaccari

 Agile Day 2007, Bologna, 23 novembre




                                    (cc) Some rights reserved.
ReadMe
Per vedere funzionare l'applicazione:
 * modifica /etc/hosts inserendo
      1 2 7 . 0 . 0 . 1 x x x . y y y. i t
      10.0.1.2 xxx.zzz.it
* inserisci i seguenti plugin di Firefox:
  * M o d i f i c a g l i h e a d e r : https://addons.mozilla.org/en-US/firefox/addon/967
    v a i s u To o l s - > M o d i f y H e a d e r s e a g g i u n g i :
    MSISDN = 393928390078
    PA RT Y- I D = 3 4 3 5 3 2 5 2
  * U s e r a g e n t sw i t c h e r : https://addons.mozilla.org/en-US/firefox/addon/59
    s a l v a r e i l f i l e h t t p : / / x x x . s o u r c e s e n s e . c o m / f i l e s / z e r o 9 / u s e r a g e n t s w i t c h e r. x m l
    e importarlo

* esegui quot;script/create_databases.shquot;
* esegui quot;script/start.shquot;
* p u n t a i l b row s e r a http://localhost:8080/progetto/p.do?page=Home
create_databases.sh
#!/bin/bash
if [ ! -d db ]; then
   echo quot;Questo script deve essere eseguito nella dir principale del progettoquot;
   exit 1
fi
echo 'Drop databases...'
mysqladmin -uroot --force drop db
mysqladmin -uroot --force drop db_test

echo 'Create databases...'
mysqladmin -uroot create db
mysqladmin -uroot create db_test
echo quot;grant all on db.* to db@localhost identified by 'db';quot; | mysql -uroot
echo quot;grant all on db_test.* to db@localhost identified by 'db';quot; | mysql -uroot

echo 'Build schema...'
cat db/db-schema.sql | mysql -udb db -pdb
cat db/db-schema.sql | mysql -udb db_test -pdb

echo 'Populate development...'
mysql -udb -pdb db < db/populate_db.sql

echo 'Done!'
start.sh
#!/bin/bash
if [ -z quot;${CMT_DEVELOPMENT_UPLOAD}quot; ] ; then
 echo quot;Deve essere settata la variabile di ambiente CMT_DEVELOPMENT_UPLOADquot;;
 exit 1;
fi

ABS_PATH=$(cd $(dirname $0); cd ..; pwd)
CATALINA_HOME=quot;$ABS_PATH/tomcat-5.5.25quot;

rm -rf $CATALINA_HOME/logs/*
rm -rf $CATALINA_HOME/webapps/progetto*

ant clean
ant deploy

ln -s /tmp $CATALINA_HOME/webapps/progetto/dynamicImages/upload

$CATALINA_HOME/bin/catalina.sh jpda start

tail -f $CATALINA_HOME/logs/catalina.out
Log
Log

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=
   org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=
   %5p %c{1}:%L - %m%n
log4j.rootLogger=INFO, stdout
Refactoring servlet
     Spot the differences
Il dilemma


•   Non posso rifattorizzare senza test
•   Ma il codice è così ingarbugliato, che
•   Non posso testare senza rifattorizzare
Il dilemma


•   Non posso cambiare il codice senza testare
•   Non posso testare senza cambiare il codice
L’algoritmo

•   Trova il punto da modificare
•   Rompi le dipendenze
•   Scrivi i test
•   Modifica; rifattorizza
Rompere le dipendenze


•   Controfigure
•   Cuciture
•   Oggetti umili
Controfigure
•   Come testare una servlet?
•   Senza usare un web server?




•   HttpServletRequest: 54 metodi!
Extract method
Sfrutta le cuciture
Test di integrazione
http://httpunit.sourceforge.net/
Refactoring servlet
Sensazioni
Tentazioni




             xkcd.com
Test jsp
       @Test
       public void testHomePage() throws Exception {
           FakePageContext pc = new FakePageContext();
           setRequestAttribute(quot;DEVICECAPABILITIESquot;, pc.capabilities);

             get(quot;/home.jspquot;);

             output().shouldContain(quot;NO-CACHEquot;);
       }


....
       protected void request(String path, String httpMethod) throws Exception {
           JspCompiler compiler = JspCompilerFactory.newInstance();
           compiler.setWebRoot(getWebRoot());
           compiler.setOutputDirectory(getOutputDirectory());
           Jsp jsp = compiler.compile(path, substituteTaglibs);
           execution = jsp.request(httpMethod, requestAttributes, sessionAttributes);
       }


http://sourceforge.net/projects/jsptest
Dipendenze

     JavaGameRetriever                                       BillingService

public JavaGameRetriever() { this(new BillingService()); }
public JavaGameRetriever(BillingService billingService)

public class FakeBillingService extends BillingService




                                                         FakeBillingService
Configurazioni
    <target name=quot;preparequot;>
      <copy todir=quot;./web/WEB-INF/quot;>
        <fileset dir=quot;${conf.dir}quot;>
          <include name=quot;ApplicationResource.propertiesquot;/>
          <include name=quot;web.xmlquot; />
        </fileset>
    ...

    <target name=quot;cleanquot;>
       <delete file=quot;./web/WEB-INF/
                     ApplicationResource.propertiesquot;/>
       <delete file=quot;./web/WEB-INF/web.xmlquot; />




               createWarForPreProduction.sh

    #!/bin/bash
    ant clean
    ant war -Dconf.dir=conf/preproduction
Risultati
Dopo                             Prima




       ...di tutto il progetto
Risultati
Dopo                      Prima




       ...delle servlet
Risultati


> Coverage: 10 % su 26056 loc
> Tempi: consegna on time - 7 settimane in un team di 3
Non perdere la testa

•   Pianifica per feature
•   Automatizza tutto
•   Scrivi test
•   Rifattorizza
•   Lavora (interattivamente) il meno possibile!
(cc) Tommaso Torti & Matteo Vaccari 2007. Published in Italy.
Attribuzione – Non commerciale – Condividi allo stesso modo 2.5

Contenu connexe

Tendances

Php mysql e cms
Php mysql e cmsPhp mysql e cms
Php mysql e cmsorestJump
 
Web Performance Optimization
Web Performance OptimizationWeb Performance Optimization
Web Performance OptimizationAlessandro Martin
 
Gestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerGestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerMassimiliano Arione
 
Consigli per iniziare tdd
Consigli per iniziare tddConsigli per iniziare tdd
Consigli per iniziare tddTassoman ☺
 
Dev Ops Italia 2015 - Per capire Desired State Configuration
Dev Ops Italia 2015 - Per capire Desired State ConfigurationDev Ops Italia 2015 - Per capire Desired State Configuration
Dev Ops Italia 2015 - Per capire Desired State ConfigurationGiulio Vian
 

Tendances (7)

Php mysql e cms
Php mysql e cmsPhp mysql e cms
Php mysql e cms
 
Web Performance Optimization
Web Performance OptimizationWeb Performance Optimization
Web Performance Optimization
 
Php mysql3
Php mysql3Php mysql3
Php mysql3
 
Gestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerGestione delle dipendenze con Composer
Gestione delle dipendenze con Composer
 
Consigli per iniziare tdd
Consigli per iniziare tddConsigli per iniziare tdd
Consigli per iniziare tdd
 
Html5 e PHP
Html5 e PHPHtml5 e PHP
Html5 e PHP
 
Dev Ops Italia 2015 - Per capire Desired State Configuration
Dev Ops Italia 2015 - Per capire Desired State ConfigurationDev Ops Italia 2015 - Per capire Desired State Configuration
Dev Ops Italia 2015 - Per capire Desired State Configuration
 

En vedette

Assistance- and Knowledge-Services for Smart Production
Assistance- and Knowledge-Services for Smart ProductionAssistance- and Knowledge-Services for Smart Production
Assistance- and Knowledge-Services for Smart ProductionCarsten Ullrich
 
ιστορια στ' 4. βενετοί,
ιστορια στ' 4. βενετοί,ιστορια στ' 4. βενετοί,
ιστορια στ' 4. βενετοί,Margarita Gerouki
 
Why Web 2.0 is Good for Learning and for Research: Principles and Prototypes
Why Web 2.0 is Good for Learning and for Research: Principles and PrototypesWhy Web 2.0 is Good for Learning and for Research: Principles and Prototypes
Why Web 2.0 is Good for Learning and for Research: Principles and PrototypesCarsten Ullrich
 
Antica presentazione AJAX
Antica presentazione AJAXAntica presentazione AJAX
Antica presentazione AJAXTommaso Torti
 
Agile Day 2012 - Sviluppo agile in un contesto bancario: come far convivere t...
Agile Day 2012 - Sviluppo agile in un contesto bancario: come far convivere t...Agile Day 2012 - Sviluppo agile in un contesto bancario: come far convivere t...
Agile Day 2012 - Sviluppo agile in un contesto bancario: come far convivere t...Tommaso Torti
 
Presentazione noestimates
Presentazione noestimatesPresentazione noestimates
Presentazione noestimatesTommaso Torti
 
Education in 2020 - Open Discussion at Barcamp Spring Shanghai 2013
Education in 2020 - Open Discussion at Barcamp Spring Shanghai 2013Education in 2020 - Open Discussion at Barcamp Spring Shanghai 2013
Education in 2020 - Open Discussion at Barcamp Spring Shanghai 2013Carsten Ullrich
 

En vedette (8)

Assistance- and Knowledge-Services for Smart Production
Assistance- and Knowledge-Services for Smart ProductionAssistance- and Knowledge-Services for Smart Production
Assistance- and Knowledge-Services for Smart Production
 
ιστορια στ' 4. βενετοί,
ιστορια στ' 4. βενετοί,ιστορια στ' 4. βενετοί,
ιστορια στ' 4. βενετοί,
 
Why Web 2.0 is Good for Learning and for Research: Principles and Prototypes
Why Web 2.0 is Good for Learning and for Research: Principles and PrototypesWhy Web 2.0 is Good for Learning and for Research: Principles and Prototypes
Why Web 2.0 is Good for Learning and for Research: Principles and Prototypes
 
Sjtu221107
Sjtu221107Sjtu221107
Sjtu221107
 
Antica presentazione AJAX
Antica presentazione AJAXAntica presentazione AJAX
Antica presentazione AJAX
 
Agile Day 2012 - Sviluppo agile in un contesto bancario: come far convivere t...
Agile Day 2012 - Sviluppo agile in un contesto bancario: come far convivere t...Agile Day 2012 - Sviluppo agile in un contesto bancario: come far convivere t...
Agile Day 2012 - Sviluppo agile in un contesto bancario: come far convivere t...
 
Presentazione noestimates
Presentazione noestimatesPresentazione noestimates
Presentazione noestimates
 
Education in 2020 - Open Discussion at Barcamp Spring Shanghai 2013
Education in 2020 - Open Discussion at Barcamp Spring Shanghai 2013Education in 2020 - Open Discussion at Barcamp Spring Shanghai 2013
Education in 2020 - Open Discussion at Barcamp Spring Shanghai 2013
 

Similaire à Dominare il codice legacy

Creazione componenti con Vue js
Creazione componenti con Vue jsCreazione componenti con Vue js
Creazione componenti con Vue jsGianfranco Castro
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Railsjekil
 
Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Davide Cerbo
 
Tech Webinar: Come ottimizzare il workflow nello sviluppo di Web App
Tech Webinar: Come ottimizzare il workflow nello sviluppo di Web AppTech Webinar: Come ottimizzare il workflow nello sviluppo di Web App
Tech Webinar: Come ottimizzare il workflow nello sviluppo di Web AppCodemotion
 
Building Large Java Codebase with Bazel - CodeOne
Building Large Java Codebase with Bazel - CodeOneBuilding Large Java Codebase with Bazel - CodeOne
Building Large Java Codebase with Bazel - CodeOneNatan Silnitsky
 
Seminario team working - 21-1-2015
Seminario team working - 21-1-2015Seminario team working - 21-1-2015
Seminario team working - 21-1-2015Alessandro Loffredo
 
Java Unit Testing - In container and database testing
Java Unit Testing - In container and database testingJava Unit Testing - In container and database testing
Java Unit Testing - In container and database testingfgianneschi
 
MongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBMongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBStefano Dindo
 
Sicurezza Php (giugno 2010) Stefano Bianchini presso Ce.Se.N.A.
Sicurezza Php (giugno 2010) Stefano Bianchini presso Ce.Se.N.A.Sicurezza Php (giugno 2010) Stefano Bianchini presso Ce.Se.N.A.
Sicurezza Php (giugno 2010) Stefano Bianchini presso Ce.Se.N.A.Stefano Bianchini
 
Java Unit Testing - Introduction
Java Unit Testing - IntroductionJava Unit Testing - Introduction
Java Unit Testing - Introductionfgianneschi
 

Similaire à Dominare il codice legacy (20)

Applicazioni native in java
Applicazioni native in javaApplicazioni native in java
Applicazioni native in java
 
Novità di Asp.Net 4.0
Novità di Asp.Net 4.0Novità di Asp.Net 4.0
Novità di Asp.Net 4.0
 
#dd12 grillo daniele_xpages_tips_tricks_rev2
#dd12 grillo daniele_xpages_tips_tricks_rev2#dd12 grillo daniele_xpages_tips_tricks_rev2
#dd12 grillo daniele_xpages_tips_tricks_rev2
 
XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13
 
Creazione componenti con Vue js
Creazione componenti con Vue jsCreazione componenti con Vue js
Creazione componenti con Vue js
 
Il testing con zend framework
Il testing con zend frameworkIl testing con zend framework
Il testing con zend framework
 
Il testing con zend framework
Il testing con zend frameworkIl testing con zend framework
Il testing con zend framework
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Rails
 
Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)
 
Hexagonal architecture ita
Hexagonal architecture itaHexagonal architecture ita
Hexagonal architecture ita
 
Tech Webinar: Come ottimizzare il workflow nello sviluppo di Web App
Tech Webinar: Come ottimizzare il workflow nello sviluppo di Web AppTech Webinar: Come ottimizzare il workflow nello sviluppo di Web App
Tech Webinar: Come ottimizzare il workflow nello sviluppo di Web App
 
Building Large Java Codebase with Bazel - CodeOne
Building Large Java Codebase with Bazel - CodeOneBuilding Large Java Codebase with Bazel - CodeOne
Building Large Java Codebase with Bazel - CodeOne
 
Linux Day 2009 LAMP HowTo
Linux Day 2009 LAMP HowToLinux Day 2009 LAMP HowTo
Linux Day 2009 LAMP HowTo
 
Seminario team working - 21-1-2015
Seminario team working - 21-1-2015Seminario team working - 21-1-2015
Seminario team working - 21-1-2015
 
Java Unit Testing - In container and database testing
Java Unit Testing - In container and database testingJava Unit Testing - In container and database testing
Java Unit Testing - In container and database testing
 
MongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBMongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDB
 
Sicurezza Php (giugno 2010) Stefano Bianchini presso Ce.Se.N.A.
Sicurezza Php (giugno 2010) Stefano Bianchini presso Ce.Se.N.A.Sicurezza Php (giugno 2010) Stefano Bianchini presso Ce.Se.N.A.
Sicurezza Php (giugno 2010) Stefano Bianchini presso Ce.Se.N.A.
 
Java Unit Testing - Introduction
Java Unit Testing - IntroductionJava Unit Testing - Introduction
Java Unit Testing - Introduction
 
TuxIsAlive
TuxIsAliveTuxIsAlive
TuxIsAlive
 
Devianze
DevianzeDevianze
Devianze
 

Dominare il codice legacy

  • 1. Dominare il codice ereditato Tommaso Torti e Matteo Vaccari Agile Day 2007, Bologna, 23 novembre (cc) Some rights reserved.
  • 2. ReadMe Per vedere funzionare l'applicazione: * modifica /etc/hosts inserendo 1 2 7 . 0 . 0 . 1 x x x . y y y. i t 10.0.1.2 xxx.zzz.it * inserisci i seguenti plugin di Firefox: * M o d i f i c a g l i h e a d e r : https://addons.mozilla.org/en-US/firefox/addon/967 v a i s u To o l s - > M o d i f y H e a d e r s e a g g i u n g i : MSISDN = 393928390078 PA RT Y- I D = 3 4 3 5 3 2 5 2 * U s e r a g e n t sw i t c h e r : https://addons.mozilla.org/en-US/firefox/addon/59 s a l v a r e i l f i l e h t t p : / / x x x . s o u r c e s e n s e . c o m / f i l e s / z e r o 9 / u s e r a g e n t s w i t c h e r. x m l e importarlo * esegui quot;script/create_databases.shquot; * esegui quot;script/start.shquot; * p u n t a i l b row s e r a http://localhost:8080/progetto/p.do?page=Home
  • 3. create_databases.sh #!/bin/bash if [ ! -d db ]; then echo quot;Questo script deve essere eseguito nella dir principale del progettoquot; exit 1 fi echo 'Drop databases...' mysqladmin -uroot --force drop db mysqladmin -uroot --force drop db_test echo 'Create databases...' mysqladmin -uroot create db mysqladmin -uroot create db_test echo quot;grant all on db.* to db@localhost identified by 'db';quot; | mysql -uroot echo quot;grant all on db_test.* to db@localhost identified by 'db';quot; | mysql -uroot echo 'Build schema...' cat db/db-schema.sql | mysql -udb db -pdb cat db/db-schema.sql | mysql -udb db_test -pdb echo 'Populate development...' mysql -udb -pdb db < db/populate_db.sql echo 'Done!'
  • 4. start.sh #!/bin/bash if [ -z quot;${CMT_DEVELOPMENT_UPLOAD}quot; ] ; then echo quot;Deve essere settata la variabile di ambiente CMT_DEVELOPMENT_UPLOADquot;; exit 1; fi ABS_PATH=$(cd $(dirname $0); cd ..; pwd) CATALINA_HOME=quot;$ABS_PATH/tomcat-5.5.25quot; rm -rf $CATALINA_HOME/logs/* rm -rf $CATALINA_HOME/webapps/progetto* ant clean ant deploy ln -s /tmp $CATALINA_HOME/webapps/progetto/dynamicImages/upload $CATALINA_HOME/bin/catalina.sh jpda start tail -f $CATALINA_HOME/logs/catalina.out
  • 5. Log
  • 6. Log log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout= org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern= %5p %c{1}:%L - %m%n log4j.rootLogger=INFO, stdout
  • 7. Refactoring servlet Spot the differences
  • 8.
  • 9. Il dilemma • Non posso rifattorizzare senza test • Ma il codice è così ingarbugliato, che • Non posso testare senza rifattorizzare
  • 10. Il dilemma • Non posso cambiare il codice senza testare • Non posso testare senza cambiare il codice
  • 11. L’algoritmo • Trova il punto da modificare • Rompi le dipendenze • Scrivi i test • Modifica; rifattorizza
  • 12. Rompere le dipendenze • Controfigure • Cuciture • Oggetti umili
  • 13. Controfigure • Come testare una servlet? • Senza usare un web server? • HttpServletRequest: 54 metodi!
  • 14.
  • 15.
  • 22. Tentazioni xkcd.com
  • 23. Test jsp @Test public void testHomePage() throws Exception { FakePageContext pc = new FakePageContext(); setRequestAttribute(quot;DEVICECAPABILITIESquot;, pc.capabilities); get(quot;/home.jspquot;); output().shouldContain(quot;NO-CACHEquot;); } .... protected void request(String path, String httpMethod) throws Exception { JspCompiler compiler = JspCompilerFactory.newInstance(); compiler.setWebRoot(getWebRoot()); compiler.setOutputDirectory(getOutputDirectory()); Jsp jsp = compiler.compile(path, substituteTaglibs); execution = jsp.request(httpMethod, requestAttributes, sessionAttributes); } http://sourceforge.net/projects/jsptest
  • 24. Dipendenze JavaGameRetriever BillingService public JavaGameRetriever() { this(new BillingService()); } public JavaGameRetriever(BillingService billingService) public class FakeBillingService extends BillingService FakeBillingService
  • 25. Configurazioni <target name=quot;preparequot;> <copy todir=quot;./web/WEB-INF/quot;> <fileset dir=quot;${conf.dir}quot;> <include name=quot;ApplicationResource.propertiesquot;/> <include name=quot;web.xmlquot; /> </fileset> ... <target name=quot;cleanquot;> <delete file=quot;./web/WEB-INF/ ApplicationResource.propertiesquot;/> <delete file=quot;./web/WEB-INF/web.xmlquot; /> createWarForPreProduction.sh #!/bin/bash ant clean ant war -Dconf.dir=conf/preproduction
  • 26. Risultati Dopo Prima ...di tutto il progetto
  • 27. Risultati Dopo Prima ...delle servlet
  • 28. Risultati > Coverage: 10 % su 26056 loc > Tempi: consegna on time - 7 settimane in un team di 3
  • 29. Non perdere la testa • Pianifica per feature • Automatizza tutto • Scrivi test • Rifattorizza • Lavora (interattivamente) il meno possibile!
  • 30. (cc) Tommaso Torti & Matteo Vaccari 2007. Published in Italy. Attribuzione – Non commerciale – Condividi allo stesso modo 2.5