Testing http://blogs.ugidotnet.org/rgm/category/Testing.aspx Testing it-IT Gian Maria Ricci Subtext Version 2.6.0.0 Questo &egrave; un post di test http://blogs.ugidotnet.org/rgm/archive/2016/08/30/questo-egrave-un-post-di-test.aspx <p>Questo è un post di test, non consideratelo. :)</p><img src="http://blogs.ugidotnet.org/rgm/aggbug/102208.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2016/08/30/questo-egrave-un-post-di-test.aspx Tue, 30 Aug 2016 20:52:36 GMT http://blogs.ugidotnet.org/rgm/archive/2016/08/30/questo-egrave-un-post-di-test.aspx#feedback 24 http://blogs.ugidotnet.org/rgm/comments/commentRss/102208.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/102208.aspx Fiddler alla riscossa http://blogs.ugidotnet.org/rgm/archive/2009/06/16/fiddler-alla-riscossa.aspx <p>Personalmente non posso vivere senza <a href="http://www.fiddler2.com/fiddler2/">fiddler</a>, ed un’altra prova della potenza di questo tool la trovate <a href="http://blogs.msdn.com/ace_team/archive/2009/05/29/how-do-i-set-up-fiddler-s-reverse-proxy-to-create-a-vsts-2008-web-test.aspx">qui</a>, nel blog dell’Ace Team,  in cui viene mostrato come fiddler possa anche registrare il traffico producendo poi un bel Web Test che potete includere in visual studio. Il processo è un po macchinoso, ma in alcune situazioni può pagare decisamente la fatica spesa.</p> <p>alk.</p> <p>Tags: <a href="http://technorati.com/tag/Testing" rel="tag">Testing</a></p><img src="http://blogs.ugidotnet.org/rgm/aggbug/96441.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2009/06/16/fiddler-alla-riscossa.aspx Tue, 16 Jun 2009 10:26:14 GMT http://blogs.ugidotnet.org/rgm/archive/2009/06/16/fiddler-alla-riscossa.aspx#feedback http://blogs.ugidotnet.org/rgm/comments/commentRss/96441.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/96441.aspx Controllare I log http://blogs.ugidotnet.org/rgm/archive/2008/01/03/90543.aspx <p>Effetturare log estesi delle proprie applicazioni è decisamente conveniente, solo che ogni tanto è necessario andare a controllare il file di log anche se tutto va bene……giusto per capire la dimensione </p><p><img src="http://www.nablasoft.com/alkampfer/itablog/010308_1436_Controllare1.png" alt="" /> </p><p>Su una macchina di produzione stavo per zippare una vecchia versione di un servizio prima di mettere la nuova e ho visto che lo zip richiedeva 3 ore…ho notato che la dimensione della cartella era di più di 4 GB,………. Mi debbo segnare quindi come promemoria di controllare ogni tanto il file di log dei miei applicativi :D </p><p>Alk.</p><img src="http://blogs.ugidotnet.org/rgm/aggbug/90543.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2008/01/03/90543.aspx Thu, 03 Jan 2008 16:39:24 GMT http://blogs.ugidotnet.org/rgm/archive/2008/01/03/90543.aspx#feedback 2 http://blogs.ugidotnet.org/rgm/comments/commentRss/90543.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/90543.aspx Nunit e interfacce fluenti http://blogs.ugidotnet.org/rgm/archive/2007/12/01/90043.aspx <p>Giovedi mentre tornavo da Luserna, nell'ultimo tratto di treno non ho resistito a tenere il portatile chiuso ed ho un po esteso quello che avevo iniziato in un <a href="http://blogs.ugidotnet.org/rgm/archive/2007/11/25/89925.aspx">precedente post</a>. L'argomento è quello di fare test con interfacce fluenti, ed un post di <a href="http://blogs.ugidotnet.org/adrian/archive/2007/11/29/90017.aspx">adrian</a> il giorno dopo cade a fagiolo. In sostanza le interfacce fluenti permettono di scrivere codice che è sicuramente più chiaro e quindi più semplice da mantenere, meno error prone e cosi via. In una mezzoretta di treno regionale sballottante ho preso il progetto relativo al post precedente, ed ho modificato un paio di cose per permettere una sintassi di questo tipo. </p><p style="background: white"><span style="font-family:Consolas"><span style="color:black">[</span><span style="color:#2b91af">Test</span><span style="color:black">] </span></span></p><p style="background: white"><span style="font-family:Consolas"><span style="color:blue">public</span><span style="color:black"> </span><span style="color:blue">void</span><span style="color:black"> TestChainWithOrNoneExplicit() { </span></span></p><p style="background: white"><span style="font-family:Consolas"><span style="color:black">   </span><span style="color:#2b91af">List</span><span style="color:black">&lt;</span><span style="color:#2b91af">AnEntity</span><span style="color:black">&gt; al = CreateTestListOne(); </span></span></p><p style="background: white"><span style="font-family:Consolas"><span style="color:black">   </span><span style="color:#2b91af">Assert</span><span style="color:black">.That(al, </span></span></p><p style="background: white"><span style="font-family:Consolas"><span style="color:black">      </span><span style="color:#2b91af">MyHas</span><span style="color:black">.Twice.Property(</span><span style="color:#a31515">"PropertyA"</span><span style="color:black">, </span><span style="color:#a31515">"q"</span><span style="color:black">) </span></span></p><p style="background: white"><span style="font-family:Consolas"><span style="color:black">      .Or.One.Property(</span><span style="color:#a31515">"PropertyB"</span><span style="color:black">, </span><span style="color:#a31515">"w"</span><span style="color:black">)); </span></span></p><p style="background: white"><span style="color:black; font-family:Consolas">} </span></p><p>Il codice è ancora veramente grezzo e sicuramente ci sono molti punti dove intervenire, ma nonostante questo la sintassi è decisamente piacevole. Leggendo il test e vedendo Has.Twice.Property(..).Or.One.Property(..) si capisce subito che stiamo cercando in una collection due elementi con la propertyA uguale a "q" oppure un elemento con PropertyB pari a "w". Il <a href="http://www.nablasoft.com/alkampfer/itablog/somenunithelpers.zip">codice lo trovate qui</a>, è scritto sul treno per cui ;)… </p><p>Alk.</p><img src="http://blogs.ugidotnet.org/rgm/aggbug/90043.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2007/12/01/90043.aspx Sat, 01 Dec 2007 10:43:42 GMT http://blogs.ugidotnet.org/rgm/archive/2007/12/01/90043.aspx#feedback http://blogs.ugidotnet.org/rgm/comments/commentRss/90043.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/90043.aspx Assert Sulle collezioni http://blogs.ugidotnet.org/rgm/archive/2007/11/26/89925.aspx <p>Molto spesso nei test si deve verificare se una collezione di entity contiene un oggetto con una proprietà di un dato valore, in questo caso non si può utilizzare il classico Contains della collection ma nunit ci viene in aiuto fornendo alcuni syntax helper interessanti. Considerate una classe chiamata AnEntity con due proprietà di tipo stringa, chiamate rispettivamente PropertyA e PropertyB, ecco un test interessante </p> <p><span style="font-family: Consolas;"><span style="color: black;">[</span><span style="color: rgb(43, 145, 175);">Test</span><span style="color: black;">]<br /> </span><span style="color: blue;">public</span><span style="color: black;"> </span><span style="color: blue;">void</span><span style="color: black;"> AnotherCollectionTest() {<br />    </span><span style="color: rgb(43, 145, 175);">List</span><span style="color: black;">&lt;</span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">&gt; al = </span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">List</span><span style="color: black;">&lt;</span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">&gt;();<br />    al.Add(</span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">(</span><span style="color: rgb(163, 21, 21);">"A"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"B"</span><span style="color: black;">));<br />    al.Add(</span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">(</span><span style="color: rgb(163, 21, 21);">"C"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"B"</span><span style="color: black;">));<br />    al.Add(</span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">(</span><span style="color: rgb(163, 21, 21);">"A"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"B"</span><span style="color: black;">));<br />    </span><span style="color: rgb(43, 145, 175);">Assert</span><span style="color: black;">.That(al, </span><span style="color: rgb(43, 145, 175);">Has</span><span style="color: black;">.All.Property(</span><span style="color: rgb(163, 21, 21);">"PropertyB"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"B"</span><span style="color: black;">));<br />    </span><span style="color: rgb(43, 145, 175);">Assert</span><span style="color: black;">.That(al, </span><span style="color: rgb(43, 145, 175);">Has</span><span style="color: black;">.Some.Property(</span><span style="color: rgb(163, 21, 21);">"PropertyA"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"C"</span><span style="color: black;">));<br />    </span><span style="color: rgb(43, 145, 175);">Assert</span><span style="color: black;">.That(al, </span><span style="color: rgb(43, 145, 175);">Has</span><span style="color: black;">.None.Property(</span><span style="color: rgb(163, 21, 21);">"PropertyB"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"KK"</span><span style="color: black;">));<br /> } </span></span></p> <p>Come potete vedere ho una lista tipizzata, ci metto dentro tre entità e poi faccio tre test. Il primo verifica che tutti gli oggetti abbiano la proprietà PropertyB pari a B, il secondo controlla che almeno uno abbia la PropertyA pari a C, mentre il terzo verifica infine che nessuno abbia la PropertyB pari a K. Si evincono subito alcune mancanze, non è infatti possibile controllare che un numero esatto di elementi soddisfi il constraint, in particolare manca la verifica che uno ed un solo elemento abbia una proprietà di un valore desiderato. Naturalmente non ci vuole molto a strutturare una interfaccia fluente che permetta di fare: </p> <p><span style="font-family: Consolas;"><span style="color: rgb(43, 145, 175);">Assert</span><span style="color: black;">.That(al, </span><span style="color: rgb(43, 145, 175);">MyHas</span><span style="color: black;">.One.Property(</span><span style="color: rgb(163, 21, 21);">"PropertyA"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"C"</span><span style="color: black;">));<br /> </span><span style="color: rgb(43, 145, 175);">Assert</span><span style="color: black;">.That(al, </span><span style="color: rgb(43, 145, 175);">MyHas</span><span style="color: black;">.Twice.Property(</span><span style="color: rgb(163, 21, 21);">"PropertyA"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"A"</span><span style="color: black;">));<br /> </span><span style="color: rgb(43, 145, 175);">Assert</span><span style="color: black;">.That(al, </span><span style="color: rgb(43, 145, 175);">MyHas</span><span style="color: black;">.Count(3).Property(</span><span style="color: rgb(163, 21, 21);">"PropertyB"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"B"</span><span style="color: black;">)); </span></span></p> <p>Oppure ci si può spingere anche un po' più in la e fare composizione tramite And e fare un assert di questo tipo </p> <p style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span style="font-family: Consolas;"><span style="color: black;">[</span><span style="color: rgb(43, 145, 175);">Test</span><span style="color: black;">]<br /> </span><span style="color: blue;">public</span><span style="color: black;"> </span><span style="color: blue;">void</span><span style="color: black;"> TestChainWithAnd() {<br />    </span><span style="color: rgb(43, 145, 175);">List</span><span style="color: black;">&lt;</span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">&gt; al = </span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">List</span><span style="color: black;">&lt;</span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">&gt;();<br />    al.Add(</span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">(</span><span style="color: rgb(163, 21, 21);">"A"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"B"</span><span style="color: black;">));<br />    al.Add(</span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">(</span><span style="color: rgb(163, 21, 21);">"C"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"B"</span><span style="color: black;">));<br />    al.Add(</span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">(</span><span style="color: rgb(163, 21, 21);">"A"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"w"</span><span style="color: black;">));<br />    al.Add(</span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">(</span><span style="color: rgb(163, 21, 21);">"q"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"r"</span><span style="color: black;">));<br />    al.Add(</span><span style="color: blue;">new</span><span style="color: black;"> </span><span style="color: rgb(43, 145, 175);">AnEntity</span><span style="color: black;">(</span><span style="color: rgb(163, 21, 21);">"q"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"w"</span><span style="color: black;">));<br />    </span><span style="color: rgb(43, 145, 175);">Assert</span><span style="color: black;">.That(al, </span><span style="color: rgb(43, 145, 175);">MyHas</span><span style="color: black;">.Twice.Property(</span><span style="color: rgb(163, 21, 21);">"PropertyA"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"q"</span><span style="color: black;">).Property(</span><span style="color: rgb(163, 21, 21);">"PropertyB"</span><span style="color: black;">, </span><span style="color: rgb(163, 21, 21);">"w"</span><span style="color: black;">));<br /> } </span></span></p> <p style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">  </p> <p style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">In questo caso sto asserendo che la collezione abbia due elementi con PropertyA pari a "q" e due con PropertyB pari a "w", componendo le asserzioni con And. </p> <p>Se volete <a href="http://www.nablasoft.com/Alkampfer/itablog/SomeNunitHelpers.7z">potete scaricare il piccolo esempietto qui</a>, è tutto fatto al volo, ma può essere uno spunto. </p> <p>Alk. </p> Technorati Tags: <a rel="tag" href="http://technorati.com/tag/testing">testing</a>   <a rel="tag" href="http://technorati.com/tag/nunit">nunit</a><img src="http://blogs.ugidotnet.org/rgm/aggbug/89925.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2007/11/26/89925.aspx Mon, 26 Nov 2007 00:00:59 GMT http://blogs.ugidotnet.org/rgm/archive/2007/11/26/89925.aspx#feedback 2 http://blogs.ugidotnet.org/rgm/comments/commentRss/89925.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/89925.aspx Nunit, forse dovrebbero manutere meglio il sito http://blogs.ugidotnet.org/rgm/archive/2007/11/25/89923.aspx <p>Stasera mi faccio un giro su <a href="http://www.nunit.org">www.nunit.org</a>, controllo e dico…ancora siamo alla versione 2.4.3….ma è una vita che non aggiornano..poi ale che è a due passi da me fa, ma io nel sito vedo la 2.4.5….????? morale della favola, su <a href="http://www.nunit.org">www.nunit.org</a> il sito non è più aggiornato per cui andate su <a href="http://www.nunit.com">www.nunit.com</a> , solo che in questo sito purtroppo i link sono tutti down per ora e non mi fa scaricare nulla sigh. </p><p>Alk.</p><img src="http://blogs.ugidotnet.org/rgm/aggbug/89923.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2007/11/25/89923.aspx Sun, 25 Nov 2007 19:40:22 GMT http://blogs.ugidotnet.org/rgm/archive/2007/11/25/89923.aspx#feedback 2 http://blogs.ugidotnet.org/rgm/comments/commentRss/89923.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/89923.aspx Chi testa i test? http://blogs.ugidotnet.org/rgm/archive/2007/11/20/89822.aspx <p>Ricordo che al TechEd si parlava proprio con <a href="http://blogs.ugidotnet.org/topics/Default.aspx">Mauro</a> di questo problema. Non sono un fanatico del TDD e lo utilizzo raramente, però sono un accanito sostenitore dei test, senza fare fondamentalismo, talvolta scrivo i test prima, talvolta invece li scrivo dopo, non testo tutto ma cerco di creare una batteria di test che sia in grado di verificare le parti più delicate del codice. In generale mi piace avere un supporto di test quando faccio re factoring. </p><p>Talvolta, soprattutto per le strutture MVC in cui ho interfacce complicate, i test iniziano perl a diventare decisamente complessi, con forte uso di <a href="http://xunitpatterns.com/Test%20Double.html">test double</a>, e quindi talvolta capita che si fa il test, poi si scrive il codice, si ottiene una barra rossa e quando si va a controllare in dettaglio si scopre che il test è fatto male. Questo solleva una questione decisamente delicata, chi si assicura che i test siano veramente corretti? La morale è che i test vanno tenuti il più semplici possibile, se un test è troppo complesso allora si rischia che. </p><ol><li>Abbia errori il test e non il codice testato </li><li>Sia fragile e quindi va mantenuto troppo spesso </li><li>Sia poco significativo. </li><li>Sia lento </li></ol><p>In particolare il terzo punto è interessante, se un test è complesso può fallire per molte ragioni e quindi dal suo fallimento non si <em>capisce che c'è qualche cosa che non va, ma non si sa cosa</em>, per cui forse vale la pena chiedersi se non valga la pena droppare il test stesso. Ricordate infatti che un buon test vi fa capire dove cercare l'errore solamente dal nome o a limite dalla stringa di errore del Nunit. </p><p>Keep your tests simple <span style="font-family:Wingdings">J</span>. </p><p>Alk. </p><img src="http://blogs.ugidotnet.org/rgm/aggbug/89822.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2007/11/20/89822.aspx Tue, 20 Nov 2007 14:26:55 GMT http://blogs.ugidotnet.org/rgm/archive/2007/11/20/89822.aspx#feedback 4 http://blogs.ugidotnet.org/rgm/comments/commentRss/89822.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/89822.aspx Favorire il Test Double per gli oggetti singleton http://blogs.ugidotnet.org/rgm/archive/2007/10/19/89055.aspx <p>Il <a href="http://xunitpatterns.com/Test%20Double.html">test double</a>, è una tecnica utilissima per aumentare la "testabilità" del codice, ma come fare per usare questa tecnica in maniera efficiente. Un pattern che uso costantemente è quello dell'override per le istanze singleton. Faccio un esempio. Se in un progetto ho un DAL molto standard che usa un Dao per tabella (un table module) gli oggetti Dao sono solitamente senza stato, per questa ragione utilizzo il pattern <a href="http://martinfowler.com/eaaCatalog/registry.html">Registry</a> in cui tengo le istanze singleton dei miei Dao. (Questo quando non posso usare Nhibernate :P). In sostanza ovunque il codice necessiti di un dao non fa altro che chiamare ad esempio Registry.CustomerDao, dove Registry è una classe statica. Questa struttura è forse anche troppo semplice, ma per progetti molto ridotti con accesso limitato a 2 o 3 tabelle può anche risultare sufficiente senza scomodare contenitori di inversione di controllo e vari. L'interessante è vedere come viene implementato l'accesso ai Dao. </p><p><span style="font-family:Consolas"><span style="color:blue">private</span><span style="color:black"> </span><span style="color:blue">static</span><span style="color:black"> </span><span style="color:#2b91af">IDdtDao</span><span style="color:black"> ddtDao;<br /></span><span style="color:blue">private</span><span style="color:black"> </span><span style="color:blue">static</span><span style="color:black"> </span><span style="color:#2b91af">IDdtDao</span><span style="color:black"> DefaultDdtDao {<br />   </span><span style="color:blue">get</span><span style="color:black"> { </span><span style="color:blue">return</span><span style="color:black"> ddtDao ?? (ddtDao = </span><span style="color:blue">new</span><span style="color:black"> </span><span style="color:#2b91af">ConcreteDdtDao</span><span style="color:black">()); }<br />}<br /></span><span style="color:blue">public</span><span style="color:black"> </span><span style="color:blue">static</span><span style="color:black"> </span><span style="color:#2b91af">IDdtDao</span><span style="color:black"> DdtDao {<br />   </span><span style="color:blue">get</span><span style="color:black"> { </span><span style="color:blue">return</span><span style="color:black"> overridingDdtDao ?? DefaultDdtDao; }<br />}<br /></span><span style="color:blue">private</span><span style="color:black"> </span><span style="color:blue">static</span><span style="color:black"> </span><span style="color:#2b91af">IDdtDao</span><span style="color:black"> overridingDdtDao;<br /></span><span style="color:blue">public</span><span style="color:black"> </span><span style="color:blue">static</span><span style="color:black"> </span><span style="color:#2b91af">IDisposable</span><span style="color:black"> OverrideDdtDao(</span><span style="color:#2b91af">IDdtDao</span><span style="color:black"> overrideDdtDao) {<br />   overridingDdtDao = overrideDdtDao;<br />   </span><span style="color:blue">return</span><span style="color:black"> </span><span style="color:blue">new</span><span style="color:black"> </span><span style="color:#2b91af">DisposableAction</span><span style="color:black">(</span><span style="color:blue">delegate</span><span style="color:black">() {<br />      overridingDdtDao = </span><span style="color:blue">null</span><span style="color:black">;<br />   });<br />} </span></span></p><p>Prima di tutto ogni Dao ha la sua interfaccia (per fare test double), il registry ha una proprietà chiamata DefaultDao che utilizza il LazyInitialization, ma la cosa interessante è che è presente una ulteriore istanza di Dao chiamata <em>overridingDdtDao</em>. L'utilizzatore accede all'istanza tramite la proprietà DdtDao che ritorna l'overridingDao se quest'ultimo è diverso da null. La funzione OverrideDdtDao() serve appunto ad impostare l'overridingDao e restituisce una <a href="http://www.ayende.com/Blog/archive/8065.aspx">DisposableAction</a>, il cui unico scopo è riportare il valore di overridingDdtDao a null. Tutto questo codice permette di fare un test di questo tipo. </p><p><span style="font-family:Consolas"><span style="color:#2b91af">IDdtDao</span><span style="color:black"> dao = mMockery.CreateMock&lt;</span><span style="color:#2b91af">IDdtDao</span><span style="color:black">&gt;();<br /></span><span style="color:blue">using</span><span style="color:black"> (mMockery.Record()) {<br />   </span><span style="color:#2b91af">…</span><span style="color:black"><br />}<br /></span><span style="color:blue">using</span><span style="color:black"> (</span><span style="color:#2b91af">Registry</span><span style="color:black">.OverrideDdtDao(dao))) {<br />   </span><span style="color:green">//in questo scope ogni oggetto che prende il DdtDao dal registry ottiene invece il mock.</span><span style="color:black"> <br />} </span></span></p><p>E il gioco è fatto, in questo modo io posso creare degli scope con la keyword using all'interno dei quali gli oggetti del registry sono rimpiazzati da TestDouble. Il SUT a questo punto ignora tutta questa struttura e chiamando <em>Registry.DdtDao</em> durante il test lavora con un TestDouble :P. </p><p>Alk.</p><img src="http://blogs.ugidotnet.org/rgm/aggbug/89055.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2007/10/19/89055.aspx Fri, 19 Oct 2007 11:44:05 GMT http://blogs.ugidotnet.org/rgm/archive/2007/10/19/89055.aspx#feedback 3 http://blogs.ugidotnet.org/rgm/comments/commentRss/89055.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/89055.aspx Gestire il teardown di una fixture http://blogs.ugidotnet.org/rgm/archive/2007/09/08/88189.aspx <img src="http://blogs.ugidotnet.org/rgm/aggbug/88189.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2007/09/08/88189.aspx Sat, 08 Sep 2007 08:45:07 GMT http://blogs.ugidotnet.org/rgm/archive/2007/09/08/88189.aspx#feedback http://blogs.ugidotnet.org/rgm/comments/commentRss/88189.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/88189.aspx Testare codice Legacy http://blogs.ugidotnet.org/rgm/archive/2007/08/14/87814.aspx <p>I progetti costruiti con TDD oppure pensati per il "design for testabiliy" sono creati e pensati per essere "testati" con facilità, purtroppo così non è per i sistemi legacy. Quando si mette mano ad un sistema preesistente per rifattorizzarlo è di primaria necessità costuire una batteria di test i più dettagliati possibile, ma spesso si incontrano difficoltà. Un caso tipico è una funzione di questo tipo: </p><p><img src="http://www.nablasoft.com/alkampfer/itablog/081407_1101_Testarecodi1.png" alt="" /> </p><p>In questo caso il SUT (System Under Test) esegue codice in base ad un settaggio che è memorizzato su un database. Questa tipologia di codice è molto comune e rende difficile effettuare il test, soprattutto perché dal test si deve essere in grado di esercitare entrambi i percorsi della funzione da verificare. La prima soluzione è quella di utilizzare un <a href="http://xunitpatterns.com/Database%20Sandbox.html"><em>Database Sandbox</em></a><em> </em>che permetta di eseguire i vari test fornendo al SUT i valori desiderati per il parametro mysetting. Il problema in esame deriva da un problema più generale che è rappresentato nella figura seguente. </p><p><img src="http://www.nablasoft.com/alkampfer/itablog/081407_1101_Testarecodi2.png" alt="" />Il DOC rappresenta il <em>Depend On Component</em> ovvero un componente da cui il SUT dipende, nel nostro caso è il database che fornisce un <a href="http://xunitpatterns.com/indirect%20input.html"><em>indirect input</em></a> ovvero un valore di input indiretto al SUT. Come detto precedentemente un <em>database sandbox </em>risolve il problema, si crea infatti un istanza di database per ogni tester e la si precarica prima di ogni test con il valore desiderato in modo da creare la <a href="http://xunitpatterns.com/test%20fixture%20-%20xUnit.html">test fixture</a> desiderata. Questa soluzione porta con se però alcune spiacevoli conseguenze, tra cui il test smell <a href="http://xunitpatterns.com/Slow%20Tests.html"><em>Slow Test</em></a><em>, </em>sempre presente quando ci si interfaccia direttamente con un database. Questa soluzione permette di impostare gli input indiretti del SUT agendo direttamente sul DOC. </p><p>Una soluzione alternativa che presenta il minimo impatto sul sistema legacy viene dal <a href="http://xunitpatterns.com/Test-Specific%20Subclass.html"><em>Test Specific Subclass</em></a>, che probabilmente costituisce la soluzione a meno impatto per il SUT. La prima cosa da fare è cambiare la signature della funzione <em>ReadSettingFromDatabase()</em> in modo che sia non più statica privata, ma virtuale e protetta, fatto questo si crea una classe che eredita dal SUT e si fa l'override della funzione ReadSettingFromDatabase(). </p><p><img src="http://www.nablasoft.com/alkampfer/itablog/081407_1101_Testarecodi3.png" alt="" /> </p><p>Cosi facendo è possibile utilizzare la classe TestExampleSUT nei propri test e grazie al fatto che la funzione ReadSettingFromDatabase() è virtuale, si può forzare un valore di ritorno dal proprio test rendendo quindi banale esercitare entrambi i percorsi del metodo DoSomething. Il test cosi costruito è inoltre più veloce perché il SUT non ha bisogno di accedere ad un vero database, ma il vantaggio più grande di questa tecnica è che il SUT non ha più dipendenze dal DOC e questo è stato fatto senza cambiare l'interfaccia pubblica del SUT ed intervenendo in maniera minima su di esso. Il codice in produzione continua ad accedere al database per recuperare il valore del settaggio, mentre il codice di test è auto consistente e non ha più input indiretti. </p><p>La tecnica del <a href="http://xunitpatterns.com/Test-Specific%20Subclass.html"><em>Test Specific Subclass</em></a><em> </em>permette quindi di aumentare la <em>Testabilità </em> del codice legacy intervenendo in maniera minimale sul SUT. </p><p>Alk.</p><img src="http://blogs.ugidotnet.org/rgm/aggbug/87814.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2007/08/14/87814.aspx Tue, 14 Aug 2007 00:02:45 GMT http://blogs.ugidotnet.org/rgm/archive/2007/08/14/87814.aspx#feedback http://blogs.ugidotnet.org/rgm/comments/commentRss/87814.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/87814.aspx