<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>in Web we Trust &#187; tdd</title>
	<atom:link href="http://blog.danilosanchi.net/tag/tdd/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.danilosanchi.net</link>
	<description>storie, pensieri, idee...</description>
	<lastBuildDate>Tue, 22 Apr 2025 13:55:16 +0000</lastBuildDate>
	<language>it-IT</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.39</generator>
	<item>
		<title>Giocando con Selenium</title>
		<link>http://blog.danilosanchi.net/2014/02/10/giocando-con-selenium/</link>
		<comments>http://blog.danilosanchi.net/2014/02/10/giocando-con-selenium/#comments</comments>
		<pubDate>Mon, 10 Feb 2014 16:58:00 +0000</pubDate>
		<dc:creator><![CDATA[Danilo]]></dc:creator>
				<category><![CDATA[Sviluppo]]></category>
		<category><![CDATA[behat]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mink]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.danilosanchi.net/?p=194</guid>
		<description><![CDATA[E&#8217; parecchio che conosco Selenium, credo dal 2009 quando l&#8217;ho visto usare in un workshop di Francesco Trucchia al PHPDay in quel di Verona. Francesco ci mostrava come si poteva rifattorizzare un&#8217;applicazione dopo averne ingabbiato il comportamento con test funzionali. &#8230; <a href="http://blog.danilosanchi.net/2014/02/10/giocando-con-selenium/">Continua a leggere <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.danilosanchi.net/2014/02/10/giocando-con-selenium/selenium/" rel="attachment wp-att-206"><img class="alignright size-full wp-image-206" alt="selenium" src="http://blog.danilosanchi.net/current/wp/wp-content/uploads/2014/02/selenium.png" width="162" height="174" /></a>E&#8217; parecchio che conosco <a title="Selenium" href="http://docs.seleniumhq.org/" target="_blank">Selenium</a>, credo dal 2009 quando l&#8217;ho visto usare in un workshop di <a title="Francesco Trucchia" href="http://www.francescotrucchia.it/" target="_blank">Francesco Trucchia</a> al <a title="PHPDay" href="http://2013.phpday.it/" target="_blank">PHPDay</a> in quel di Verona. Francesco ci mostrava come si poteva rifattorizzare un&#8217;applicazione dopo averne ingabbiato il comportamento con test funzionali.</p>
<p><em>Traduzione: prima di modificare il codice di un&#8217;applicazione che non conosci, magari scritta male, generalmente da un&#8217;altro, è buona norma scrivere un programma che simuli l&#8217;intervento dell&#8217;utente e svolga tutte le operazioni più importanti sull&#8217;applicazione stessa.<span id="more-194"></span></em></p>
<p>Con Selenium è possibile pilotare il browser e quindi muoversi tra le pagine di un sito, compilare form, cliccare link, draggare elementi. Quando facciamo questo sulla nostra applicazione stiamo eseguendo un test automatico per verificare che si comporti come ci aspettiamo. Quando invece lo facciamo su un altro sito per raggiungere delle informazioni ed estrarle periodicamente, stiamo facendo web scraping.</p>
<p>La leggenda narra che con il Selenium IDE sia possibile registrare delle macro, mentre un utente reale esegue le operazioni sull&#8217;applicazione, per poi rieseguirle in un secondo momento e verificare che questa continui a comportarsi nello stesso modo, nonostante il programmatore abbia cambiato la sua struttura interna.</p>
<p>Ad oggi questo mito è stato ormai sfatato poiché è evidente che il modo più pratico per utilizzare Selenium è quello di programmare manualmente le operazioni da eseguire attraverso una delle varie librerie a disposizione per ciascuno linguaggio di programmazione.</p>
<p>Per funzionare Selenium deve poter pilotare un browser, ad esempio Firefox, ed un browser ha bisogno di un ambiente grafico per funzionare. Su un server web però non abbiamo un ambiente grafico. Sul proprio computer invece è piuttosto difficile ed irritante fare qualsiasi altra cosa mentre Firefox continua ad aprirsi e a sbilinare da solo.</p>
<p>Possiamo però simulare l&#8217;ambiente grafico e dire a Selenium di usarlo. La parolina magica, suggeritami da<a title="Giorgio Sironi" href="http://www.giorgiosironi.com/" target="_blank"> Giorgio Sironi</a> all&#8217;<a title="Agile Day" href="http://www.agileday.it/" target="_blank">AgileDay2013</a>, è <strong>xvfb</strong>.</p>
<p>Installiamo <a title="Xvfb" href="http://www.x.org/releases/current/doc/man/man1/Xvfb.1.xhtml" target="_blank">Xvfb</a> e facciamo in modo che venga lanciato all&#8217;avvio della macchina:</p>
<pre>sudo apt-get install xvfb
sudo vim /etc/init.d/xvfb</pre>
<pre><em># /etc/init.d/xvfb</em>

#!/bin/bash

if [ -z "$1" ]; then
echo "`basename $0` {start|stop}"
exit
fi

case "$1" in
start)
/usr/bin/Xvfb :99 -ac -screen 0 1024x768x8 &gt; /dev/null &amp;
;;

stop)
killall Xvfb
;;
esac</pre>
<pre>sudo chmod 755 /etc/init.d/xvfb
vim ~/.bash_aliases</pre>
<pre><em># ~/.bash_aliases</em>

...
alias xvfb='etc/init.d/xvfb'</pre>
<pre>sudo /etc/init.d/update-rc.d xvfb default 10</pre>
<p>Ora è possibile avviare xvfb tramite il comando xvfb start e fermarlo tramite xvfb stop</p>
<p>Ora installiamo Selenium.<br />
scarichiamo da <a href="http://docs.seleniumhq.org/download/">http://docs.seleniumhq.org/download/</a> l’ultima versione di <strong>Selenium Server (formerly the Selenium RC Server)</strong>:<br />
Lo mettiamo tra le nostre librerie e poi facciamo la stessa cosa che abbiamo fatto per xvfb, ne semplifichiamo l&#8217;esecuzione.</p>
<pre>wget <a href="http://selenium.googlecode.com/files/selenium-server-standalone-2.39.0.jar">http://selenium.googlecode.com/files/selenium-server-standalone-2.39.0.jar</a>
sudo mkdir /var/lib/selenium
sudo mv selenium-server-standalone-2.39.0.jar /var/lib/selenium
cd /var/lib/selenium
sudo ln -s selenium-server-standalone-2.39.0.jar selenium-server.jar
sudo vim /etc/init.d/selenium</pre>
<pre><em># /etc/init.d/selenium</em>

#!/bin/bash

if [ -z "$1" ]; then
echo "`basename $0` {start|stop}"
exit
fi

export DISPLAY=":99"
case "$2" in
show)
export DISPLAY=":0"
;;
esac

case "$1" in
start)
java -jar /var/lib/selenium/selenium-server.jar -browserSessionReuse &gt; /dev/null &amp;
;;

stop)
curl http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer
;;
esac</pre>
<pre>sudo 755 selenium
vim ~/.bash_aliases</pre>
<pre><em># ~/.bash_aliases</em>
...
alias selenium='etc/init.d/selenium'</pre>
<p>Ora è possibile avviare selenium nell&#8217;ambiente grafico generato da xvfb con il comando selenium start oppure in quello reale (se c&#8217;è) con selenium start show, e fermarlo con selenium stop</p>
<p>In alcuni casi potrebbe essere interessante lanciarlo all&#8217;avvio del server: lo si può fare con</p>
<pre>sudo /etc/init.d/update-rc.d selenium default 20</pre>
<p>Se non l&#8217;avete fatto non rimane che installare Firefox</p>
<pre>sudo apt-get install firefox</pre>
<p>Ora possiamo creare test funzionali con <a href="http://phpunit.de/manual/3.7/en/selenium.html">Selenium2 PHPUnit Extension</a> oppure far web scraping con <a href="http://mink.behat.org/">Mink<br />
</a></p>
<p>Questo articolo non è altro che un&#8217;assemblaggio ed una personalizzazione delle pratiche lette nei seguenti:</p>
<p><a href="http://www.installationpage.com/selenium/how-to-run-selenium-headless-firefox-in-ubuntu/" target="_blank">http://www.installationpage.com/selenium/how-to-run-selenium-headless-firefox-in-ubuntu/<br />
</a><a href="http://www.labelmedia.co.uk/blog/setting-up-selenium-server-on-a-headless-jenkins-ci-build-machine.html" target="_blank">http://www.labelmedia.co.uk/blog/setting-up-selenium-server-on-a-headless-jenkins-ci-build-machine.html<br />
</a><a href="http://testerinyou.blogspot.it/2011/05/run-selenium-rc-using-command-prompt.html">http://testerinyou.blogspot.it/2011/05/run-selenium-rc-using-command-prompt.html</a></p>
<p>Direi che è tutto. Ciao!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilosanchi.net/2014/02/10/giocando-con-selenium/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pioritree e Silex</title>
		<link>http://blog.danilosanchi.net/2013/01/27/pioritree-e-silex/</link>
		<comments>http://blog.danilosanchi.net/2013/01/27/pioritree-e-silex/#comments</comments>
		<pubDate>Sun, 27 Jan 2013 19:17:21 +0000</pubDate>
		<dc:creator><![CDATA[Danilo]]></dc:creator>
				<category><![CDATA[Idee]]></category>
		<category><![CDATA[Sviluppo]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[idea]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[silex]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[time]]></category>
		<category><![CDATA[todo]]></category>

		<guid isPermaLink="false">http://blog.danilosanchi.net/?p=123</guid>
		<description><![CDATA[Circa due anni fa stavo (finalmente) studiando i design pattern su Head First Design Patterns, un libro semplice, pieno di figure, sicuramente più accessibile (ai programmatori un po&#8217; meno svegli) del ben più noto Design Patterns: Elementi per il riuso di &#8230; <a href="http://blog.danilosanchi.net/2013/01/27/pioritree-e-silex/">Continua a leggere <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.danilosanchi.net/2013/01/27/vino-vecchio-nella-botte-nuova/post_it_tree/" rel="attachment wp-att-134"><img class="alignright  wp-image-134" alt="post_it_tree" src="http://blog.danilosanchi.net/current/wp/wp-content/uploads/2013/01/post_it_tree-267x300.jpg" width="214" height="240" /></a>Circa due anni fa stavo (finalmente) studiando i <strong>design pattern</strong> su <em><a title="Head First Design Patterns" href="http://www.headfirstlabs.com/books/hfdp/" target="_blank">Head First Design Patterns</a></em>, un libro semplice, pieno di figure, sicuramente più accessibile (ai programmatori un po&#8217; meno svegli) del ben più noto<em> <a title="Design Patterns" href="http://en.wikipedia.org/wiki/Design_Patterns" target="_blank">Design Patterns: Elementi per il riuso di software ad oggetti</a></em>, il quale è più un <strong>catalogo</strong> da consultare che un testo di <strong>apprendimento</strong>.</p>
<p>Beh, avevo letto del <strong><a title="Composite Pattern" href="http://en.wikipedia.org/wiki/Composite_pattern" target="_blank">Composite Pattern</a></strong> e mi era venuta in mente un&#8217;<strong>idea</strong> per metter in pratica quanto appreso.<br />
Cercavo un modo per <strong>dedicare il giusto tempo</strong> alle mille attività che dovevo/volevo svolgere senza trascurare nulla, ma soprattutto senza trascurare le cose più importanti:</p>
<p><em>Quanto tempo devo dedicare alla pulizia della casa? Quanto ne posso dedicare alle attività della mia associazione? Ma della pulizia della casa, quanto tempo dedico alla cucina e quanto alla camera da letto?</em></p>
<p><em><span id="more-123"></span></em></p>
<p>Insomma volevo costruire una <strong>gerarchia</strong> (un albero) di <strong>attività</strong> da svolgere, in cui ogni attività potesse essere suddivisa in sottoattività e così via. Ad ogni attività avrei quindi assegnato un <strong>livello di priorità</strong> (da 1 a 10 per esempio). Avrei infine scelto un <strong>monte ore</strong> di riferimento (ad esempio 100 ore) da <strong>distribuire automaticamente</strong> a ciascuna attività in base alle loro priorità. Il <strong>Composite Pattern</strong> era perfetto per gestire <strong>gerarchie di elementi</strong> e avrei potuto sperimentare un approccio <strong><a title="Test First" href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">TDD</a></strong>. Il nome che gli avrei dato sarebbe stato <strong>Prioritree</strong>.</p>
<p>Non mi ci volle molto per realizzare un <strong>prototipo. </strong>Sarebbe stato impossibile implementare le classi che gestiscono una gerarchia senza l&#8217;ausilio di <strong>test unitari</strong>.<br />
Praticamente si doveva definire la propria gerarchia di attività con le loro priorità ed il monte ore assegnato su un file <strong>Yaml</strong>:</p>
<pre><span style="color: #0000ff;">// mytasks.yml</span>
<span style="color: #008000;">Root</span>:
  data: timeBox=100
  children:
     <span style="color: #008000;">Casa</span>:
        data: priority=10
        children:
           <span style="color: #008000;">Camera da letto</span>:
              data: priority=6
           <span style="color: #008000;">Bagno</span>:
              data: priority=10
           <span style="color: #008000;">Cucina</span>:
              data: priority=8
     <span style="color: #008000;">Associazione</span>:
        data: priority=6
        children:
           <span style="color: #008000;">Sito</span>:
              data: priority=2
           <span style="color: #008000;">Facebook</span>:
              data: priority=4
           <span style="color: #008000;">Eventi</span>:
              data: priority=10</pre>
<p>eseguendo un semplice <em>php index.php </em>il file veniva arricchito con le ore assegnate a ciascuna attività.</p>
<pre><span style="color: #0000ff;">// mytasks.yml</span>
<span style="color: #008000;">Root</span>:
   data: usedTime=0; timeBox=100; progress=0%; time=0/100
   children:
      <span style="color: #008000;">Casa</span>:
         data: usedTime=0; priority=10; progress=0%; time=0/62.5
         children:
            <span style="color: #008000;">Camera da letto</span>:
               data: usedTime=0; priority=6; progress=0%; time=0/15.63
            <span style="color: #008000;">Bagno</span>:
               data: usedTime=0; priority=10; progress=0%; time=0/26.04
            <span style="color: #008000;">Cucina</span>:
               data: usedTime=0; priority=8; progress=0%; time=0/20.83
      <span style="color: #008000;">Associazione</span>:
         data: usedTime=0; priority=6; progress=0%; time=0/37.5
         children:
            <span style="color: #008000;">Sito</span>:
               data: usedTime=0; priority=2; progress=0%; time=0/4.69
            <span style="color: #008000;">Facebook</span>:
               data: usedTime=0; priority=4; progress=0%; time=0/9.38
            <span style="color: #008000;">Eventi</span>:
               data: usedTime=0; priority=10; progress=0%; time=0/23.44</pre>
<p>Successivamente era possibile specificare il <strong>tempo utilizzato</strong> per ciascuna attività  a qualsiasi livello di dettaglio impostando <em>usedTime;</em> rilanciando <em>php index.php</em> veniva aggiornato il progresso percentuale e le ore assegnate su tutte le attività discendenti ed ascendenti.</p>
<pre><span style="color: #0000ff;">// mytasks.yml</span>
<span style="color: #008000;">Root</span>:
   data: usedTime=0; timeBox=100; progress=<span style="color: #0000ff;"><strong>11%</strong></span>; time=<span style="color: #0000ff;"><strong>11</strong></span>/100
   children:
      <span style="color: #008000;">Casa</span>:
         data: usedTime=<strong><span style="color: #ff0000;">2</span></strong>; priority=10; progress=<span style="color: #0000ff;"><strong>17.6%</strong></span>; time=<span style="color: #0000ff;"><strong>11</strong></span>/62.5
         children:
            <span style="color: #008000;">Camera da letto</span>:
               data: usedTime=<span style="color: #ff0000;"><strong>4</strong></span>; priority=6; progress=<span style="color: #0000ff;"><strong>29.87%</strong></span>; time=<span style="color: #0000ff;"><strong>4.67</strong></span>/15.63
            <span style="color: #008000;">Bagno</span>:
               data: usedTime=<span style="color: #ff0000;"><strong>5</strong></span>; priority=10; progress=<span style="color: #0000ff;"><strong>21.76%</strong></span>; time=<span style="color: #0000ff;"><strong>5.67</strong></span>/26.04
            <span style="color: #008000;">Cucina</span>:
               data: usedTime=0; priority=8; progress=<span style="color: #0000ff;"><strong>3.2%</strong></span>; time=<span style="color: #0000ff;"><strong>0.67</strong></span>/20.83
      <span style="color: #008000;">Associazione</span>:
         data: usedTime=0; priority=6; progress=0%; time=0/37.5
         children:
            <span style="color: #008000;">Sito</span>:
               data: usedTime=0; priority=2; progress=0%; time=0/4.69
            <span style="color: #008000;">Facebook</span>:
               data: usedTime=0; priority=4; progress=0%; time=0/9.38
            <span style="color: #008000;">Eventi</span>:
               data: usedTime=0; priority=10; progress=0%; time=0/23.44</pre>
<p>Era possibile cambiare le priorità delle attività oppure cambiare la struttura dell&#8217;albero in qualsiasi momento: le ore assegnate cambiavano, nessun problema.</p>
<p>Faceva altre cose ovviamente, come resettare il monte ore portandosi dietro i <em>debiti</em> e i <em>crediti</em> del monte ore precedente, ma l&#8217;idea in soldoni era questa.</p>
<p>Utilizzai come contenitore un <strong>microframework</strong> che stavo realizzando per i miei progetti personali ispirato a quanto avevo letto di <a title="Symfony 1.x" href="http://symfony.com/legacy" target="_blank"><strong>Symfony</strong></a> e dell&#8217;archiettura <a title="MVC" href="http://it.wikipedia.org/wiki/Model-View-Controller" target="_blank"><strong>MVC</strong></a>. Solo l&#8217;anno scorso imparai ad utilizzare <a title="Git" href="http://git-scm.com/" target="_blank"><strong>Git</strong></a> e <a title="Github" href="https://github.com" target="_blank"><strong>Github</strong></a> e vi pubblicai il mio Prioritree.</p>
<p>Quest&#8217;estate, però, ho imparato ad utilizzare <a title="Silex" href="http://silex.sensiolabs.org/" target="_blank"><strong>Silex</strong></a>, il fratellino minore di <a title="Symfony 2" href="http://symfony.com" target="_blank"><strong>Symfony 2</strong></a>, grazie ad un lavoretto con <a title="Ideato" href="http://www.ideato.it" target="_blank"><strong>Ideato</strong></a>. Quindi ho pensato di riprendere il Prioritree e sostituire il mio incompleto e rozzo microframework con Silex, al fine di costruire in un secondo momento una&#8217;interfaccia web decente per quello che ora è solo un set di classi.</p>
<p>Grazie ai vecchi test il <strong>porting</strong> è stato rapido e indolore e questo è il <a title="Prioritree" href="https://github.com/danielsan80/Prioritree" target="_blank"><strong>risultato</strong></a>.</p>
<p>Ho cercato di fare <em>commit</em> piccole e significative in modo da mettere in evidenza tutti i passaggi fatti per cambiare contenitore. I tag <a title="v1.0" href="https://github.com/danielsan80/Prioritree/tree/v1.0" target="_blank"><strong>v1.0</strong></a> e <a title="v2.0" href="https://github.com/danielsan80/Prioritree/tree/v2.0" target="_blank"><strong>v2.0</strong></a>  corrispondono rispettivamente al Prioritree prima e dopo il <em>travaso</em> in Silex.</p>
<p>Ora manca il <em>Readme</em> in <em>markdown</em> e buttar su un&#8217;interfaccia web semplice semplice per poterlo pubblicare e rendere disponibile a tutti. E&#8217; la prima volta che a distanza di anni riesco a riprendere del vecchio codice e a riutilizzarlo senza che mi faccia schifo. <img src="http://blog.danilosanchi.net/current/wp/wp-includes/images/smilies/simple-smile.png" alt=":)" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.danilosanchi.net/2013/01/27/pioritree-e-silex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
