<?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>Le blog de Mathieu ATTAL &#187; Les tests</title>
	<atom:link href="https://blog.developpez.com/zapoutix/pcategory/les-tests/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/zapoutix</link>
	<description></description>
	<lastBuildDate>Sat, 11 Jul 2009 10:21:36 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Comment utiliser un fichier de configuration (.config) avec FitNesse.NET</title>
		<link>https://blog.developpez.com/zapoutix/p7808/les-tests/comment_utiliser_un_fichier_de_configura</link>
		<comments>https://blog.developpez.com/zapoutix/p7808/les-tests/comment_utiliser_un_fichier_de_configura#comments</comments>
		<pubDate>Sat, 27 Jun 2009 14:44:09 +0000</pubDate>
		<dc:creator><![CDATA[zapoutix]]></dc:creator>
				<category><![CDATA[Les tests]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le probleme avec FitNesse.NET est que lors de l&#8217;éxecution d&#8217;une page de test le fichier de configuration de l&#8217;assembly testé n&#8217;est pas pris en compte. Enfaite le wiki Fitnesse execute l&#8217;assembly FitServer.exe qui lui meme éxécute l&#8217;assembly a tester, donc le fichier de configuration loadé est &#171;&#160;FitServer.exe.config&#171;&#160;, celui -ci doit se trouver dans le meme répertoire que l&#8217;assembly FitServer.exe. Wiki -&#62; FitServer.exe -&#62; FitServer.exe.config -&#62; AssemblyTest Pour résoudre se problème, il existe plusieurs possibilitées : [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le probleme avec FitNesse.NET est que lors de l&rsquo;éxecution d&rsquo;une page de test le fichier de configuration de l&rsquo;assembly testé n&rsquo;est pas pris en compte.<br />
Enfaite le wiki Fitnesse execute l&rsquo;assembly FitServer.exe qui lui meme éxécute l&rsquo;assembly a tester, donc le fichier de configuration loadé est &laquo;&nbsp;<strong>FitServer.exe.config</strong>&laquo;&nbsp;, celui -ci doit se trouver dans le meme répertoire que l&rsquo;assembly FitServer.exe.</p>
<p>Wiki -&gt; FitServer.exe -&gt; FitServer.exe.config -&gt; AssemblyTest</p>
<p>Pour résoudre se problème, il existe plusieurs possibilitées :<br />
<span id="more-3"></span><br />
<strong>Copier le contenu de votre fichier de configuration dans le fichier FitServer.config</strong><br />
Le probleme avec cette methode c&rsquo;est qu&rsquo;il faut autant de FitServer.exe que de fichier de configuration différent :</p>
<ul>
<li>Assembly 1</li>
<li>
<ul>
<li>Assembly1.dll</li>
<li> Assembly1.dll.config</li>
<li> FitServer.exe</li>
<li> FitServer.exe.config</li>
</ul>
</li>
</ul>
<p>Avec <em>FitServer.exe.conf = Assembly1.dll.config</em></p>
<ul>
<li>Assembly 2</li>
<li>
<ul>
<li>Assembly2.dll</li>
<li> Assembly2.dll.config</li>
<li> FitServer.exe</li>
<li> FitServer.exe.config</li>
</ul>
</li>
</ul>
<p>Avec <em>FitServer.exe.conf = Assembly2.dll.config</em></p>
<p>De plus il faut configurer les pages Wiki pour qu&rsquo;elles éxécutent le bon FitServer en fonction de l&rsquo;assembly a tester.<br />
Si on a 10 assemblies a tester ca peut devenir compliqué.</p>
<p><strong>Utiliser la Suite Configuration</strong><br />
FitServer.exe peut être executé avec un argument &laquo;&nbsp;<strong>-c</strong>&nbsp;&raquo; qui est la Suite Configuration, qui permet au FitSever.exe de prendre un fichier de configuration en paramètre.<br />
Pour utilisé ce fichier de configuration il suffit d&rsquo;ajouter une define a la page de test ou a une suite :</p>
<blockquote><p>!define COMMAND_PATTERN {%m -c mySuite.config %p}</p></blockquote>
<p>Ce fichier de configuration se presente sous la forme suivante :<br />
[sourcecode language=&rsquo;xml&rsquo;]<br />
&lt;suiteConfig&gt;<br />
    &lt;fit.Settings&gt;<br />
        &lt;appConfigFile&gt;myDomain.dll.config&lt;/appConfigFile&gt;<br />
    &lt;/fit.Settings&gt;<br />
&lt;/suiteConfig&gt;<br />
[/sourcecode]</p>
<p>Grace a ce fichier de configuration supplémentaire, un seul FitServer est nécessaire.</p>
<ul>
<li> FitServer.exe</li>
<li>Assembly 1</li>
<li>
<ul>
<li>Assembly1.dll</li>
<li> Assembly1.dll.config</li>
<li> suite.config</li>
</ul>
</li>
</ul>
<ul>
<li>Assembly 2</li>
<li>
<ul>
<li>Assembly2.dll</li>
<li> Assembly2.dll.config</li>
<li> suite.config</li>
</ul>
</li>
</ul>
<p>Plus d&rsquo;info sur le suite configuration <a href="http://www.syterra.com/FitnesseDotNet/SuiteConfigurationFile.html" target="_blank">ici</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Le TDD par l&#8217;exemple</title>
		<link>https://blog.developpez.com/zapoutix/p7776/les-tests/le_tdd_par_l_exemple</link>
		<comments>https://blog.developpez.com/zapoutix/p7776/les-tests/le_tdd_par_l_exemple#comments</comments>
		<pubDate>Sun, 21 Jun 2009 14:14:07 +0000</pubDate>
		<dc:creator><![CDATA[zapoutix]]></dc:creator>
				<category><![CDATA[Les tests]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le TDD ou Test Driven Development est une méthode permettant le développement d&#8217;une application par les tests, au lieu d&#8217;écrire le source et le tester a la fin du développement, le TDD préconise d&#8217;écrire les tests unitaires avant d&#8217;écrire le code source. Comment ca marche ? Un TDD s&#8217;écrit en 6 étapes : écrire un test vérifier qu&#8217;il échoue (car le code que l&#8217;on teste n&#8217;existe pas) écrire juste le code suffisant pour passer le [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le TDD ou Test Driven Development est une méthode permettant le développement d&rsquo;une application par les tests, au lieu d&rsquo;écrire le source et le tester a la fin du développement, le TDD préconise d&rsquo;écrire les tests unitaires avant d&rsquo;écrire le code source.</p>
<h3><strong>Comment ca marche ?</strong></h3>
<p>Un TDD s&rsquo;écrit en 6 étapes :</p>
<ul>
<li>écrire un test</li>
<li>vérifier qu&rsquo;il échoue (car le code que l&rsquo;on teste n&rsquo;existe pas)</li>
<li>écrire juste le code suffisant pour passer le test</li>
<li>vérifier que le test passe</li>
<li>Checkiner le source pour que les autres développeurs puissent l&rsquo;utiliser</li>
<li>Refactoriser le code</li>
</ul>
<p><span id="more-1"></span></p>
<h3><strong>Mais pourquoi faire ?</strong></h3>
<p>Ces tests permettent de préciser les spécifications du code, et donc son comportement ultérieur en fonction des situations auxquelles il sera exposé. Ce qui facilite la production d&rsquo;un code valide en toutes circonstances. On obtient donc un code plus juste et plus fiable.</p>
<p>En écrivant les tests d&rsquo;abord, on utilise le programme avant même qu&rsquo;il existe. On s&rsquo;assure ainsi que le code produit est testable unitairement. Il est donc impératif d&rsquo;avoir une vision précise de la manière dont on va utiliser le programme avant même d&rsquo;envisager son implémentation. Cela évite souvent des erreurs de conception dues à une précipitation dans l&rsquo;implémentation avant d&rsquo;avoir défini les objectifs.</p>
<p>De plus, le fait d&rsquo;avoir des tests augmente la confiance en soi du programmeur lors de la refactorisation du code : il sait qu&rsquo;à un moment donné les tests ont réussi. Il peut ainsi se permettre des changements radicaux de design en étant sûr, à la fin, d&rsquo;avoir un programme se comportant toujours de la même façon (si les tests réussissent toujours).</p>
<p>L&rsquo;utilisation de TDD permet la construction conjointe du programme et d&rsquo;une suite de tests de non-régression.</p>
<h3><strong>Entrons dans le vif du sujet</strong></h3>
<p>Prenons un exemple,<br />
Notre analyste nous demande de transformer le prix HT dans l&rsquo;application par le prix TTC.<br />
Nous devons donc réaliser une fonction qui transforme un prix HT en prix TTC.</p>
<p>Travaillons par étape, en premier nous devons créer un projet de tests unitaires.<br />
<img src="http://blog.attal.info/wp-content/uploads/2009/02/addtest.png" alt="Add test project" /></p>
<p>Puis nous créons une class de tests unitaires pour tester la class <span style="color: #ff0000;"><em>Price</em></span><br />
Le nom de la class de test pourra être appelée <span style="color: #ff0000;"><em>PriceTest</em></span> par exemple.</p>
<blockquote><p>Il est très important de définir une norme pour le nom des projets de test, les class de test, et les méthodes de test entre tous les développeurs pour une homogénéité du code (StyleCop)</p></blockquote>
<p><img src="http://blog.attal.info/wp-content/uploads/2009/02/addtestfile.png" alt="Add test file" /></p>
<p>Que doit faire ce test ?<br />
la réponse est relativement simple, il doit créer un objet de type <em><span style="color: #ff0000;">Price</span></em> qui a une valeur correspondant au prix HT, et ajouter une taxe a ce prix.</p>
<p>Quels sont les acteurs, les activités et les asserts du test ?</p>
<p><strong>Acteurs :</strong></p>
<ul>
<li>Un object Price</li>
<li>Le prix HT</li>
<li>Le prix TTC retourné par la fonctionnalité</li>
<li>Le prix TTC attendu</li>
</ul>
<p><strong>Activités :</strong></p>
<ul>
<li>Appeler une method de la class <em><span style="color: #ff0000;">Price </span></em>qui nous retourne un decimal de la valeur TTC</li>
</ul>
<p><strong>Asserts :</strong></p>
<ul>
<li>Vérifier que la valeur attendu est égale à la valeur retournée par la methode</li>
</ul>
<p>Prenons un scénario, si le prix HT est 50 Euros alors quelle sera la valeur TTC ?</p>
<p>Durant l&rsquo;analyse de ce scénario et l&rsquo;écriture de ce test, plusieurs questions restent sans réponses :</p>
<ul>
<li>Qu&rsquo;elle est la valeur de la taxe</li>
<li>Combien de chiffre après la virgule pour le prix TTC</li>
<li>Doit on arrondir ou couper le prix TTC </li>
</ul>
<p>Ces questions doivent être répondu par notre analyste le plus rapidement possible.<br />
Il nous répond que la taxe sera exclusivement de 19.6 et que l&rsquo;on ne doit pas arrondir la valeur TTC.</p>
<p>Ce qui donne le test suivant :</p>
<blockquote><p>
[TestMethod]<br />
public void Price_PriceTTCIs59_8_WhenPriceHTIs50()<br />
{<br />
  #region Actors<br />
  Price price;<br />
  decimal HTPrice = 50;<br />
  decimal TTCPrice;<br />
  decimal expectedTTCPrice = 59.8m;<br />
  #endregion</p>
<p>  #region Activities<br />
  price = new Price(HTPrice);<br />
  TTCPrice = price.GetTTCPrice();<br />
  #endregion</p>
<p>  #region Asserts<br />
  Assert.AreEqual(expectedTTCPrice, TTCPrice, &laquo;&nbsp;The TTC  expected price is not correct&nbsp;&raquo;);<br />
  #endregion<br />
}
</p></blockquote>
<p>Le test ne compile pas car la class <em><span style="color: #ff0000;">Price</span></em> n&rsquo;existe pas encore.<br />
Faisons une implémentation rapide de cette class.</p>
<blockquote><p>
public class Price<br />
{<br />
  private decimal _price;<br />
  public Price(decimal price)<br />
  {<br />
    _price = price;<br />
  }</p>
<p>  public decimal GetTTCPrice()<br />
  {<br />
    return 59.8m;<br />
  }<br />
}
</p></blockquote>
<p>Le test est vert, le code peut être checkiner pour que les autres développeurs puissent l&rsquo;utiliser pour l&rsquo;interface graphique par exemple.<br />
Maintenant nous pouvons prendre un peu de temps pour implémenter la methode <span style="color: #ff0000;">GetTTCPrice</span>;</p>
<blockquote><p>
public decimal GetTTCPrice()<br />
{<br />
  decimal TTCPrice;<br />
  TTCPrice = _price * 1.196m;</p>
<p>  return  TTCPrice;<br />
}
</p></blockquote>
<p>Le test reste vert la methode <span style="color: #ff0000;">GetTTCPrice</span> a l&rsquo;air de fonctionner.<br />
Ecrivons un 2 eme test pour valider notre implémentation</p>
<blockquote><p>
[TestMethod]<br />
public void Price_PriceTTCIs119_6_WhenPriceHTIs100()<br />
{<br />
  #region Actors<br />
  Price price;<br />
  decimal HTPrice = 100;<br />
  decimal TTCPrice;<br />
  decimal expectedTTCPrice = 119.6m;<br />
  #endregion</p>
<p>  #region Activities<br />
  price = new Price(HTPrice);<br />
  TTCPrice = price.GetTTCPrice();<br />
  #endregion</p>
<p>  #region Asserts<br />
  Assert.AreEqual(expectedTTCPrice, TTCPrice, &laquo;&nbsp;The TTC expected price is not correct&nbsp;&raquo;);<br />
  #endregion<br />
}
</p></blockquote>
<p>Les 2 tests sont vert, tout va bien, nous pouvons checkiner notre code.</p>
<p>Bravo nous venons de faire du TDD.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Testons les limites</title>
		<link>https://blog.developpez.com/zapoutix/p7778/les-tests/testons_les_limites</link>
		<comments>https://blog.developpez.com/zapoutix/p7778/les-tests/testons_les_limites#comments</comments>
		<pubDate>Sun, 21 Jun 2009 15:05:12 +0000</pubDate>
		<dc:creator><![CDATA[zapoutix]]></dc:creator>
				<category><![CDATA[Les tests]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Dans l&#8217;article précédent nous avons vu comment faire du TDD simplement. Les 2 tests que nous avons écrit nous permettent de tester les cas d&#8217;utilisations, mais il est important de tester les extrêmes pour limiter les exécutions non contrôlées de l&#8217;application. Pour cela nous devons déjà les définir. Reprenons l&#8217;exemple de l&#8217;article précédent avec GetTTCPrice Nous devons vérifier que si le prix HT est 0 Euros alors le prix TTC reste 0 Que ce passe [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Dans l&rsquo;article précédent nous avons vu comment faire du TDD simplement.<br />
Les 2 tests que nous avons écrit nous permettent de tester les cas d&rsquo;utilisations, mais <strong><span style="color: #ff0000;">il est important de tester les extrêmes pour limiter les exécutions non contrôlées de l&rsquo;application.</span></strong></p>
<p>Pour cela nous devons déjà les définir.<br />
Reprenons l&rsquo;exemple de l&rsquo;article précédent avec <span style="color: #ff0000;">GetTTCPrice</span></p>
<ul>
<li>Nous devons vérifier que si le prix HT est 0 Euros alors le prix TTC reste 0</li>
<li>Que ce passe t-il si le prix HT est inferieur 0 ?</li>
</ul>
<p><span id="more-2"></span></p>
<p>Pour le premier point, un test unitaire suffira, mais pour le 2 eme point, nous devons demander a notre analyste.<br />
Notre analyste nous répond tout simplement qu&rsquo;un prix négatif, ca n&rsquo;existe pas.<br />
La peste, ca n&rsquo;existait pas avant qu&rsquo;on la découvre.<br />
<strong>Si ca n&rsquo;existe pas faut-il tester ce cas ?</strong></p>
<p>Bien sur que oui, ca prend 5 minutes et ca ne mange pas de pain.<br />
Ok, on test, mais quel doit être le comportement d&rsquo;un cas qui n&rsquo;existe pas ?<br />
Le choix doit âtre pris par le développeur, donc par nous.<br />
Fonctionellement ce cas est impossible, mais techniquement c&rsquo;est tout a fait possible de passer un nombre negatif a la class <span style="color: #ff0000;">Price</span>.<br />
Si nous faisons rien pour éviter qu&rsquo;un prix soit négatif, notre application a un risque de partir dans un comportement incontrôlé, nous devons intérompre se comportement le plus rapidement, mais comment ?</p>
<ul>
<li>En mettant le prix a 0</li>
<li>En claquant une exception</li>
</ul>
<p>Beaucoup de personnes vont penser que la première solution est suffisante, mais NON arrêtez d&rsquo;être stupide, pourquoi <strong>0</strong> ? pourquoi pas <strong>5</strong> ou <strong>22</strong> ou <strong>42</strong> ? <strong>decimal.MaxValue</strong>, c&rsquo;est pas mal non plus non ?<br />
Il faut avertir l&rsquo;application qu&rsquo;il y a un problème en claquant une exception, le Framework .NET a une exception du type <strong>ArgumentException</strong>, plutôt cool non ?</p>
<p>Modifions la class Price pour gérer ce cas:</p>
<blockquote><p>
    public class Price<br />
    {<br />
        private decimal _price;</p>
<p>        public Price(decimal price)<br />
        {<br />
            if (price &lt; 0)<br />
                throw new ArgumentException(&laquo;&nbsp;Price cannot be negative&nbsp;&raquo;);</p>
<p>            _price = price;<br />
        }</p>
<p>        public decimal GetTTCPrice()<br />
        {<br />
            decimal TTCPrice;</p>
<p>            TTCPrice = _price * 1.196m;</p>
<p>            return  TTCPrice;<br />
        }<br />
    }
</p>
</blockquote>
<p>Et voila les 2 nouveaux tests unitaires pour tester les limites :</p>
<blockquote><p>
        [TestMethod]<br />
        public void Price_PriceTTCIs0_WhenPriceHTIs0()<br />
        {<br />
            #region Actors<br />
            Price price;<br />
            decimal HTPrice = 0;<br />
            decimal TTCPrice;<br />
            decimal expectedTTCPrice = 0;<br />
            #endregion</p>
<p>            #region Activities<br />
            price = new Price(HTPrice);<br />
            TTCPrice = price.GetTTCPrice();<br />
            #endregion</p>
<p>            #region Asserts<br />
            Assert.AreEqual(expectedTTCPrice, TTCPrice, &laquo;&nbsp;The TTC expected price is not correct&nbsp;&raquo;);<br />
            #endregion<br />
        }</p>
<p>        [TestMethod]<br />
        [ExpectedException(typeof(ArgumentException))]<br />
        public void Price_ThrowArgumentException_WhenPriceHTIsNegative()<br />
        {<br />
            #region Actors<br />
            Price price;<br />
            decimal HTPrice = -56;<br />
            #endregion</p>
<p>            #region Activities<br />
            price = new Price(HTPrice);<br />
            #endregion</p>
<p>        }
</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
