<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brice Favre</title>
    <description>The latest articles on DEV Community by Brice Favre (@brice).</description>
    <link>https://dev.to/brice</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F74512%2F019bc2fa-e1e4-4157-8af1-cd54b3c13100.jpeg</url>
      <title>DEV Community: Brice Favre</title>
      <link>https://dev.to/brice</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brice"/>
    <language>en</language>
    <item>
      <title>Revenir à la base : Tester une fonction de 4 lignes (et oui!)</title>
      <dc:creator>Brice Favre</dc:creator>
      <pubDate>Thu, 24 May 2018 12:27:49 +0000</pubDate>
      <link>https://dev.to/brice/revenir--la-base--tester-une-fonction-de-4-lignes-et-oui-3f86</link>
      <guid>https://dev.to/brice/revenir--la-base--tester-une-fonction-de-4-lignes-et-oui-3f86</guid>
      <description>&lt;p&gt;Cet exemple est tiré d'un cas réel de développement. Il n'a rien de très compliqué, hormis le fait que la classe testée soit abstraite mais est assez courant dans le développement.&lt;/p&gt;

&lt;p&gt;Imaginons que, dans la class Stats, nous voulions rajouter une fonction isStatusAll qui permet de vérifier que la propriété status de la classe contient all, si c'est un tableau, ou bien est égal à "all" si c'est une chaine de caractère.&lt;/p&gt;

&lt;h2&gt;
  
  
  Création de la classe de test
&lt;/h2&gt;

&lt;p&gt;La première chose à vérifier est la présence ou non de la classe de tests. Elle doit avoir le même nom que la classe suivi de tests, soit StatsTest&lt;/p&gt;

&lt;p&gt;Si elle est présente alors nous rajouterons nos tests à celle ci.&lt;/p&gt;

&lt;p&gt;Si elle n'existe pas, il suffit de la créer dans le répertoire approprié. Il suffit de suivre les conventions que l'équipe ou le responsable des tests se sont données. Dans ce répertoires nous créerons un fichier StatsTest.php contenant le code suivant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;PHPUnit\Framework\TestCase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StatsTest&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;TestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Que doit on tester et comment ?
&lt;/h2&gt;

&lt;p&gt;C'est une question qui se pose à chaque fois que l'on va écrire des tests unitaires. &lt;br&gt;
La bonne question à se poser est "Que cherche t'on à faire?" Une question qu'il convient de découper en plusieurs étapes. &lt;/p&gt;

&lt;p&gt;La première est que l'on cherche à écrire une fonction isStatusAll donc nous allons écrire, dans notre classe de test, une fonction testIsStatusAll, puis écrire la fonction elle même dans la classe Stats :&lt;/p&gt;

&lt;p&gt;Dans la classe de tests :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testIsStatusAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dans la classe Stats :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;isStatusAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// On code un simple retour pour le moment &lt;/span&gt;
        &lt;span class="c1"&gt;// pour valider la liaison entre le code et la classe de test&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensuite il suffit d'appeler la nouvelle fonction dans la classe de test. Généralement il suffit de faire quelque chose comme ça :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;   &lt;span class="nv"&gt;$object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;MyFunction&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dans notre cas, la classe Stats est une classe abstraite, il faudra donc la simuler afin de la tester. Heureusement PHPUnit pense à nous et prévoit &lt;a href="http://phpunit.readthedocs.io/fr/latest/test-doubles.html#mocker-les-traits-et-les-classes-abstraites"&gt;un système&lt;/a&gt; pour cela. Dans notre cas la fonction testIsStatusAll la création de l'objet se fera dans la manière suivante.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testIsStatusAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Le deuxième argument permet de passer des paramètres au &lt;/span&gt;
        &lt;span class="c1"&gt;// constructeur de l'objet car, &lt;/span&gt;
        &lt;span class="c1"&gt;// Fun Fact, le constructeur de Stats prend des paramètres.&lt;/span&gt;
        &lt;span class="nv"&gt;$statsItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMockForTrait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StatsItem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$statsItem&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isStatusAll&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si on lance les tests alors ils échouent... ce qui est normal :-)&lt;/p&gt;

&lt;p&gt;Une fois ce point de départ, il ne vous reste plus qu'à coder la fonction et les tests afférents. Pour des raisons pratiques, il est conseillé de faire une fonction par assertion. Dans notre cas il en existe quatre :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IsStatusAll renvoie faux si status est nul (soit la condition par défaut)&lt;/li&gt;
&lt;li&gt;IsStatusAll renvoie vrai si status est égal à "all"&lt;/li&gt;
&lt;li&gt;IsStatusAll renvoie vrai si status est un tableau et que ce tableau contient "all"&lt;/li&gt;
&lt;li&gt;IsStatusAll renvoie faut si status est un tableau et que ce tableau ne contient pas "all"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ce qui donne dans notre cas :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;   &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testIsStatusAllWithoutDocStatus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMockForTrait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Stats&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$stats&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isStatusAll&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testIsStatusAllWhereStatusIsAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMockForTrait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Stats&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$stats&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'all'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$statsItem&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isStatusAll&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testIsStatusAllWhereStatusIsAnArrayWithAllinIt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMockForTrait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Stats&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$stats&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'all'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$statsItem&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isStatusAll&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testIsStatusAllWhereStatusIsAnEmptyArray&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMockForTrait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Stats&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$stats&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$statsItem&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isStatusAll&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Les tests vous montreront si la fonction correspond à ce qu'elle doit faire... ou pas. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cet exemple montre comment, en quelques tests ont peut faire le tour d'une fonction simple. J'invite tous ceux qui n'ont pas encore franchi le pas, a commencer par ce genre de fonction. Outre l'aspect qualité, le fait de revenir sur son code permet d'éviter les erreurs bêtes et de se libérer l'esprit. Une fois les tests faits, il est très simple de coder, de se tromper, de se corriger et de délivrer une fonction conforme à ce que l'on voulait.&lt;/p&gt;

&lt;p&gt;Ce sera autant de temps de cerveau disponible pour des fonctions plus complexes, pour des problématiques plus ardues.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>php</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
