<?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>romain.getBlog( ); &#187; continuous integration</title>
	<atom:link href="http://linsolas.free.fr/wordpress/index.php/category/continuous-integration/feed/" rel="self" type="application/rss+xml" />
	<link>http://linsolas.free.fr/wordpress</link>
	<description></description>
	<lastBuildDate>Wed, 23 Jan 2013 21:29:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Chouchoutez votre JavaScript dans un projet web</title>
		<link>http://linsolas.free.fr/wordpress/index.php/2012/05/chouchoutez-votre-javascript-dans-un-projet-web/</link>
		<comments>http://linsolas.free.fr/wordpress/index.php/2012/05/chouchoutez-votre-javascript-dans-un-projet-web/#comments</comments>
		<pubDate>Thu, 03 May 2012 22:06:30 +0000</pubDate>
		<dc:creator>Romain</dc:creator>
				<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[sonar]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://linsolas.free.fr/wordpress/?p=277</guid>
		<description><![CDATA[Voilà, c&#8217;est fait ! Vous êtes venus à Devoxx France, vous avez assisté à ma présentation (ou alors vous avez juste lu mon post sur le sujet), et donc vous voulez désormais chouchouter votre code JavaScript. Pour démarrer sur le sujet, vous avez suivi les étapes écrites sur mon post, comme je l&#8217;ai fait lors [...]]]></description>
			<content:encoded><![CDATA[<p>Voilà, c&#8217;est fait ! Vous êtes venus à Devoxx France, vous avez assisté à ma présentation (ou alors vous avez juste lu mon <a href="http://linsolas.free.fr/wordpress/index.php/2012/04/chouchoutez-votre-code-javascript">post sur le sujet</a>), et donc vous voulez désormais <strong>chouchouter votre code JavaScript</strong>.</p>
<p>Pour démarrer sur le sujet, vous avez suivi les étapes écrites sur mon post, comme je l&#8217;ai fait lors de ma présentation. C&#8217;est bien joli tout ça, mais dans la vraie vie réelle, vous n&#8217;avez pas un module Maven dédié au code JavaScript. Votre code JavaScript est (bêtement) dans votre application web ! Du coup, vous vous posez des questions sur la façon de procéder, en particulier concernant les analyses Sonar&#8230;</p>
<p>Allez zou, suivez le guide !</p>
<p><span id="more-277"></span></p>
<h2>Zou, créons un projet</h2>
<p>Lors de ma présentation, j&#8217;ai utilisé l&#8217;archetype Maven <code>de.akquinet.javascript.archetypes:javascript-quickstart</code>, qui crée un squelette d&#8217;application contenant juste du JavaScript.<br />
Cette fois-ci, on va partir d&#8217;un projet web classique dans lequel on incluera notre code JavaScript. Donc quelque chose de plus proche que ce que vous avez sur votre projet !</p>
<p>Je pars donc avec l&#8217;archetype <code>org.codehaus.mojo.archetypes:webapp-javaee6</code> pour avoir un squelette d&#8217;application web. Il s&#8217;agit là de votre propre projet web&#8230; De mon côté, j&#8217;y ajoute une petite classe Java, ainsi qu&#8217;une class de test JUnit pour le fun.</p>
<p>Désormais, on peut lancer une première analyse Sonar, avec la commande <code>mvn clean install sonar:sonar</code>.</p>
<div id="attachment_272" class="wp-caption center" style="width: 750px"><a href="http://linsolas.free.fr/wordpress/wp-content/uploads/chouchoutage-1.png"><img src="http://linsolas.free.fr/wordpress/wp-content/uploads/chouchoutage-1.png" alt="" title="chouchoutage-1" width="740" height="455" class="size-full wp-image-272" /></a><p class="wp-caption-text">Jusqu'ici, tout va bien !</p></div>
<p>Maintenant, je rajoute mon code JavaScript (les fichiers <code>underscore.js</code> et <code>undescore-test.js</code>). Je les positionne respectivement dans les répertoires <code>src/main/javascript</code> et <code>src/test/javascript</code>. Il est possible d&#8217;adapter ces répertoires, bien entendu !<br />
On ajoute le fichier de configuration de <code>jsTestDriver.conf</code> qui va nous permettre de lancer nos tests JavaScript de Jasmine. On ajoute aussi dans un coin (le répertoire <code>lib/</code> disons) :</p>
<ul>
<li>le fichier <code>jasmine.js</code> ;</li>
<li>le fichier <code>jasmineAdapter.js</code> (pour lancer les tests JavaScript écrits en Jasmine avec js-test-driver) ;</li>
<li>la librairie <code>coverage-1.3.4.b.jar</code>, qui est le plugin de calcul de couverture du code JavaScript pour js-test-driver.</li>
</ul>
<p>Au final, la structure de mon projet a la tête suivante :</p>
<pre class="brush: plain;">
chouchoutage (oui, c'est le nom pourri de mon projet)
  + pom.xml
  ` src
      + lib
      |   ` coverage-1.3.4.b.jar
      |   ` jasmine.js
      |   ` jasmineAdapter.js
      + main
      |   + java
      |   |   ` ze-code-java
      |   ` javascript
      |       ` underscore.js
      + test
      |   + java
      |   |   ` test-unitaires
      |   ` javascript
      |       ` underscore-test.js
      ` webapp
          ` toute-la-partie-web
</pre>
<p>Si vous souhaitez plus d&#8217;informations sur cette étape (comme le contenu du fichier <code>jsTestDriver.conf</code> par exemple), allez jeter un oeil sur <a href="http://linsolas.free.fr/wordpress/index.php/2012/04/chouchoutez-votre-code-javascript">mon post décrivant ma session Devoxx</a>.</p>
<p>Voilà, on arrive à quelque chose qui ressemble en gros à votre projet. Maintenant, on va voir comment on va pouvoir exécuter nos codes JavaScript, et en faire l&#8217;analyse Sonar.</p>
<h2>Ne tombons pas dans les poms !</h2>
<p>Attaquons nous au problème principal : la modification du pom. Nous allons d&#8217;abord l&#8217;adapter pour exécuter nos tests JavaScript. Nous verrons ensuite pour l&#8217;analyse Sonar&#8230;</p>
<p>Ajoutons d&#8217;abord la dépendance suivante :</p>
<pre class="brush: xml;">
    &lt;dependency&gt;
        &lt;groupId&gt;com.googlecode.jstd-maven-plugin&lt;/groupId&gt;
        &lt;artifactId&gt;jstd-maven-plugin&lt;/artifactId&gt;
        &lt;version&gt;1.3.2.5&lt;/version&gt;
        &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
</pre>
<p>On ajoute ensuite le plugin de <code>jstd-maven-plugin</code> :</p>
<pre class="brush: xml;">
    &lt;plugin&gt;
        &lt;groupId&gt;com.googlecode.jstd-maven-plugin&lt;/groupId&gt;
        &lt;artifactId&gt;jstd-maven-plugin&lt;/artifactId&gt;
        &lt;version&gt;1.3.2.5&lt;/version&gt;
        &lt;configuration&gt;
            &lt;port&gt;9876&lt;/port&gt;
            &lt;!-- A adapter ! --&gt;
            &lt;browser&gt;/Applications/Firefox.app/Contents/MacOS/firefox-bin&lt;/browser&gt;
            &lt;tests&gt;all&lt;/tests&gt;
            &lt;config&gt;jsTestDriver.conf&lt;/config&gt;
            &lt;testOutput&gt;target/jstestdriver&lt;/testOutput&gt;
        &lt;/configuration&gt;
        &lt;executions&gt;
            &lt;execution&gt;
                &lt;id&gt;run-tests&lt;/id&gt;
                &lt;goals&gt;
                    &lt;goal&gt;test&lt;/goal&gt;
                &lt;/goals&gt;
            &lt;/execution&gt;
        &lt;/executions&gt;
    &lt;/plugin&gt;
</pre>
<p>Dernier point, nous ajoutons le repository contenant les plugins sus-cités :</p>
<pre class="brush: xml;">
    &lt;repositories&gt;
          &lt;repository&gt;
              &lt;id&gt;jstd-maven-plugin google code repo&lt;/id&gt;
              &lt;url&gt;http://jstd-maven-plugin.googlecode.com/svn/maven2&lt;/url&gt;
          &lt;/repository&gt;
    &lt;/repositories&gt;
    &lt;pluginRepositories&gt;
          &lt;pluginRepository&gt;
              &lt;id&gt;jstd-maven-plugin google code repo&lt;/id&gt;
              &lt;url&gt;http://jstd-maven-plugin.googlecode.com/svn/maven2&lt;/url&gt;
          &lt;/pluginRepository&gt;
    &lt;/pluginRepositories&gt;
</pre>
<p>Voilà, nous pouvons vérifier si cela fonctionne. La commande <code>mvn clean install</code> va nous le dire :</p>
<pre class="brush: plain;">
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running fr.linsolas.WorldTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.053 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- jstd-maven-plugin:1.3.2.5:test (run-tests) @ chouchoutage ---

-------------------------------------------
 J S  T E S T  D R I V E R
-------------------------------------------

Firefox: Runner reset.
................
Total 16 tests (Passed: 16; Fails: 0; Errors: 0) (10,00 ms)
  Firefox 9.0.1 Mac OS: Run 16 tests (Passed: 16; Fails: 0; Errors 0) (10,00 ms)
</pre>
<p>C&#8217;est plutôt une bonne nouvelle ça ! Surefire a lancé mon test JUnit (<code>fr.linsolas.WorldTest</code>), puis, dans un second temps, a exécuté les tests de js-test-driver.</p>
<h2>Plongeons dans l&#8217;analyse Sonar</h2>
<p>Et bien voilà, il ne nous reste plus qu&#8217;à exécuter une analyse Sonar et le tour est joué&#8230; Mais ce n&#8217;est pas si simple en fait !<br />
Sonar permet bien d&#8217;analyser un projet Java, il permet d&#8217;analyser également un projet JavaScript, mais hélas pas en même temps !<br />
Nous allons devoir donc lancer <strong>deux analyses Sonar</strong> pour arriver à nos fins.</p>
<p>Etant donné que nous ne voulons pouvoir lancer avec le même pom.xml l&#8217;analyse Sonar pour le code Java et l&#8217;analyse Sonar pour le code JavaScript, nous allons créer un profil Maven qui sera dédié à l&#8217;analyse JavaScript :</p>
<pre class="brush: xml;">
    &lt;profiles&gt;
        &lt;profile&gt;
            &lt;id&gt;js&lt;/id&gt;
            &lt;properties&gt;
                &lt;sonar.language&gt;js&lt;/sonar.language&gt;
                &lt;sonar.dynamicAnalysis&gt;reuseReports&lt;/sonar.dynamicAnalysis&gt;
            &lt;/properties&gt;
        &lt;/profile&gt;
    &lt;/profiles&gt;
</pre>
<p>Voyons voir si cela fonctionne. Lançons une première analyse avec <code>mvn clean install sonar:sonar</code>. En exécutant cette commande, l&#8217;analyse Sonar ne montre aucune différence avec celle réalisée plus tôt. Normal, me direz-vous, on reste sur l&#8217;analyse Java.<br />
Lançant maintenant la même commande, mais en activant le profile <strong>js</strong> : <code>mvn -Pjs clean install sonar:sonar</code>. Le résultat n&#8217;est pas celui attendu :</p>
<div id="attachment_273" class="wp-caption center" style="width: 766px"><a href="http://linsolas.free.fr/wordpress/wp-content/uploads/chouchoutage-2.png"><img src="http://linsolas.free.fr/wordpress/wp-content/uploads/chouchoutage-2.png" alt="" title="chouchoutage-2" width="756" height="233" class="size-full wp-image-273" /></a><p class="wp-caption-text">Ooooups</p></div>
<p>Houlà, mais on a tout cassé ! On n&#8217;obtient plus aucun chiffre, ni rien <img src='http://linsolas.free.fr/wordpress/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Le problème vient simplement du fait que le plugin JavaScript pour Sonar va chercher les sources dans le répertoire <code>src/main/java</code> au lieu de <code>src/main/javascript</code>.<br />
Il faut donc lui spécifier ce nouveau répertoire. On va donc spécifier un <code>sourceDirectory</code> dans notre profile <strong>js</strong>. Du moins on aimerait bien, car hélas Maven n&#8217;autorise pas que l&#8217;on redéfinisse ce répertoire dans un profil ! C&#8217;est étrange, mais c&#8217;est comme ça. Enfin pas tant que ça, car Maven &#8211; par défaut &#8211; n&#8217;accepte qu&#8217;un seul chemin de sources. Comme plusieurs profiles peuvent être actifs en même temps, on pourrait bidouiller les profiles pour avoir ainsi plusieurs répertoires de sources. On s&#8217;égare un peu là&#8230;<br />
Nous pourrions passer par le plugin <a href="http://mojo.codehaus.org/build-helper-maven-plugin/" onclick="pageTracker._trackPageview('/outgoing/mojo.codehaus.org/build-helper-maven-plugin/?referer=');">build-helper</a> qui permet de spécifier plusieurs répertoires de sources. Je n&#8217;en ferais rien, je vais &laquo;&nbsp;simplement&nbsp;&raquo; fourvoyer Maven en jouant avec les propriétés :</p>
<pre class="brush: xml;">
    &lt;properties&gt;
        &lt;source.dir&gt;src/main/java&lt;/source.dir&gt;
        &lt;test.source.dir&gt;src/test/java&lt;/test.source.dir&gt;
    &lt;/properties&gt;

    &lt;build&gt;
        &lt;sourceDirectory&gt;${source.dir}&lt;/sourceDirectory&gt;
        &lt;testSourceDirectory&gt;${test.source.dir}&lt;/testSourceDirectory&gt;
        ...
    &lt;/build&gt;

    &lt;profiles&gt;
        &lt;profile&gt;
            &lt;id&gt;js&lt;/id&gt;
            &lt;properties&gt;
                &lt;source.dir&gt;src/main/javascript&lt;/source.dir&gt;
                &lt;test.source.dir&gt;src/test/javascript&lt;/test.source.dir&gt;
                ...
</pre>
<p>Voilà, Maven n&#8217;y voit que du feu, et moi j&#8217;ai réussi à me débrouiller (à bidouiller disons plutôt).</p>
<p>Alors, que donne l&#8217;analyse Sonar maintenant ?</p>
<div id="attachment_274" class="wp-caption center" style="width: 753px"><a href="http://linsolas.free.fr/wordpress/wp-content/uploads/chouchoutage-3.png"><img src="http://linsolas.free.fr/wordpress/wp-content/uploads/chouchoutage-3.png" alt="" title="chouchoutage-3" width="743" height="454" class="size-full wp-image-274" /></a><p class="wp-caption-text">Voilà qui est mieux !</p></div>
<p>OUI ! Enfin, nous réussissons à obtenir notre belle analyse du code JavaScript par Sonar !</p>
<p>Et voilà, c&#8217;est fini.<br />
Vraiment ? Non !<br />
Un dernier souci se pose : si je lance l&#8217;analyse Java, j&#8217;ai un beau rapport Sonar. Mais dès que je lance l&#8217;analyse JavaScript, mon rapport JavaScript efface celui de Java !<br />
Il faut donc trouver un moyen de faire cohabiter les deux. Je propose simplement de profiter de l&#8217;option <code>sonar.branch</code> pour différencier les deux projets. On ajoute donc dans le profil <strong>js</strong> :</p>
<pre class="brush: xml;">
    &lt;profiles&gt;
        &lt;profile&gt;
            &lt;id&gt;js&lt;/id&gt;
            &lt;properties&gt;
                &lt;sonar.branch&gt;javascript&lt;/sonar.branch&gt;
                ...
</pre>
<p>Cette fois-ci, on relance les deux analyses : <code>mvn clean install sonar:sonar</code> puis <code>mvn -Pjs clean install sonar:sonar</code>.<br />
Une fois les deux commandes terminées, nous nous retrouvons avec non plus un mais deux projets Sonar :</p>
<div id="attachment_275" class="wp-caption center" style="width: 627px"><a href="http://linsolas.free.fr/wordpress/wp-content/uploads/chouchoutage-4.png"><img src="http://linsolas.free.fr/wordpress/wp-content/uploads/chouchoutage-4.png" alt="" title="chouchoutage-4" width="617" height="78" class="size-full wp-image-275" /></a><p class="wp-caption-text">Les deux font la paire</p></div>
<p>Chacun de ces projets est adapté à son langage, le premier pour Java, le second pour JavaScript.</p>
<p>Et voilà, c&#8217;est fini.<br />
Vraiment ? Cette fois, oui <img src='http://linsolas.free.fr/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>N&#8217;hésitez pas à faire part, dans les commentaires, de vos propres expériences, ou propositions d&#8217;améliorations !</p>
<a href="javascript:toggleStartStop();PicLensLite.start({feedUrl:'http://linsolas.free.fr/wordpress/wp-content/plugins/wp-piclens/mrss.php?id=277'});">Start Slide Show with PicLens Lite <img src="http://linsolas.free.fr/wordpress/wp-content/plugins/wp-piclens/PicLensButton.png" alt="PicLens" width="16" height="12" border="0" align="top"></a>]]></content:encoded>
			<wfw:commentRss>http://linsolas.free.fr/wordpress/index.php/2012/05/chouchoutez-votre-javascript-dans-un-projet-web/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Chouchoutez votre code JavaScript</title>
		<link>http://linsolas.free.fr/wordpress/index.php/2012/04/chouchoutez-votre-code-javascript/</link>
		<comments>http://linsolas.free.fr/wordpress/index.php/2012/04/chouchoutez-votre-code-javascript/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 21:14:18 +0000</pubDate>
		<dc:creator>Romain</dc:creator>
				<category><![CDATA[conférence]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[sonar]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://linsolas.free.fr/wordpress/?p=210</guid>
		<description><![CDATA[Voici la retranscription de ma session &#171;&#160;Chouchoutez votre code JavaScript&#171;&#160;, présentée lors de la première édition de Devoxx France, le mercredi 18 avril 2012. Le but de cette présentation est de montrer qu&#8217;il est aussi facile de tester et analyser son code JavaScript que son code Java. Les mêmes outils seront d&#8217;ailleurs utilisés, en particulier [...]]]></description>
			<content:encoded><![CDATA[<p>Voici la retranscription de ma session &laquo;&nbsp;<strong>Chouchoutez votre code JavaScript</strong>&laquo;&nbsp;, présentée lors de la première édition de Devoxx France, le mercredi 18 avril 2012.</p>
<p>Le but de cette présentation est de montrer qu&#8217;il est aussi facile de tester et analyser son code JavaScript que son code Java. Les mêmes outils seront d&#8217;ailleurs utilisés, en particulier Maven, Jenkins et Sonar.</p>
<p><span id="more-210"></span></p>
<p>Avant toute chose, nous allons prendre <a href="http://documentcloud.github.com/underscore/" onclick="pageTracker._trackPageview('/outgoing/documentcloud.github.com/underscore/?referer=');">underscore.js</a> comme cobaye pour nos tests. Pour information, il s&#8217;agit d&#8217;une librairie proposant une soixantaine de fonctions JS permettant de faire de la programmation fonctionnelle.</p>
<h2>Etape #1: Créer le projet</h2>
<p>Mon choix, pour la première librairie de tests, c&#8217;est <a href="http://pivotal.github.com/jasmine/" onclick="pageTracker._trackPageview('/outgoing/pivotal.github.com/jasmine/?referer=');">Jasmine</a>. Il s&#8217;agit d&#8217;une librairie avec une communauté assez active, et disposant d&#8217;un certain nombre de supports : Java et Maven, .Net, Ruby, Node.js, etc.<br />
Pour être plus précis, cette librairie va être surtout utilisée lorsque l&#8217;on souhaite faire du BDD (<em>Behavior Driven Development</em>). D&#8217;ailleurs, dans la terminologie de Jasmine, on ne parle pas de test, mais de <em>spec</em>.</p>
<p>Comme dit précédemment, <a href="http://searls.github.com/jasmine-maven-plugin/" onclick="pageTracker._trackPageview('/outgoing/searls.github.com/jasmine-maven-plugin/?referer=');">Jasmine offre un support Maven</a>. Pour ma présentation, j&#8217;opte pour la création d&#8217;un projet squelette, via un archetype Maven. Cela se fait via cette commande :</p>
<pre class="brush: plain;">mvn archetype:generate
    -DarchetypeRepository=http://searls-maven-repository.googlecode.com/svn/trunk/snapshots
    -DarchetypeGroupId=com.github.searls
    -DarchetypeArtifactId=jasmine-archetype
    -DarchetypeVersion=1.1.0.1-SNAPSHOT
    -DgroupId=fr.devoxx
    -DartifactId=chouchoutez-javascript
    -Dversion=0.0.1-SNAPSHOT</pre>
<p>Une fois ceci réalisé, nous obtenons un projet (que nous allons importer dans notre IDE préféré) ayant la structure suivante :</p>
<pre class="brush: plain;">
pom.xml
  ` src
     + main
     |  ` javascript
     |      ` quickstart.js
     ` test
        ` javascript
           ` quickstartTest.js
</pre>
<p>La partie intéressante dans le pom.xml est la déclaration du plugin Jasmine qui va permettre de lancer les tests via une commande Maven :</p>
<pre class="brush: xml;">
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;com.github.searls&lt;/groupId&gt;
                &lt;artifactId&gt;jasmine-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;1.0.1-beta-6&lt;/version&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;generateManualRunner&lt;/goal&gt;
                            &lt;goal&gt;resources&lt;/goal&gt;
                            &lt;goal&gt;testResources&lt;/goal&gt;
                            &lt;goal&gt;test&lt;/goal&gt;
                            &lt;goal&gt;preparePackage&lt;/goal&gt;
                        &lt;/goals&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
                &lt;configuration&gt;
                    &lt;jsSrcDir&gt;src/main/javascript&lt;/jsSrcDir&gt;
                    &lt;jsTestSrcDir&gt;src/test/javascript&lt;/jsTestSrcDir&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;</pre>
<p>En lançant la commande <code>mvn test</code>, on voit que le test généré par défaut par l&#8217;archetype est lancé :</p>
<pre class="brush: plain;">-------------------------------------------------------
 J A S M I N E   T E S T S
-------------------------------------------------------
[INFO]
describe The quickstart object
  it adds two numbers
[INFO]
Results:

1 specs, 0 failures</pre>
<h2>Etape #2 : Ecrire des tests</h2>
<p>Je copie mon <code>underscore.js</code> dans le répertoire <code>src/main/javascript</code>, et nous allons le tester&#8230;<br />
Jasmine propose une écriture assez intuitive des tests, assez proche de <a href="http://code.google.com/p/fest/" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/fest/?referer=');">fest-assert</a>. En voici un premier exemple :</p>
<pre class="brush: jscript;">describe(&quot;Mon premier test&quot;, function() {
    it(&quot;should be 42&quot;, function() {
        var resultat = _.max([1, 2, 3, 42]);
        expect(resultat).toBe(42);
    };
};</pre>
<p>Avec Jasmine, on crée une suite de tests en utilisant le mot <code>describe</code>, suivi de son descriptif. Ensuite, on y ajoute une série de tests (voire on imbrique de nouvelles suites), chaque test (ou plus exactement chaque <em>spec</em>) étant défini par le mot clé <code>it</code>. On écrit le code du test, puis au moment de vérifier (i.e. de réaliser les <code>assert</code>), on va simplement utiliser <code>expect</code> suivi d&#8217;un matcher (ici <code>toBe</code>). <a href="https://github.com/pivotal/jasmine/wiki/Matchers" onclick="pageTracker._trackPageview('/outgoing/github.com/pivotal/jasmine/wiki/Matchers?referer=');">Plusieurs autres matchers existent</a> (<code>toEqual</code>, <code>toBeNull</code>, <code>toBeGreaterThan</code>, <code>toContain</code>, <code>toBeUndefined</code>).</p>
<p>A nouveau, je vérifie mes tests avec la commande Maven <code>mvn clean test</code>.</p>
<p>Voici mon fichier de tests final de la librairie underscore.js :</p>
<pre class="brush: jscript;">describe(&quot;Mon premier test&quot;, function() {

  it(&quot;should be 42&quot;, function() {
    var max = _.max([1, 2, 42]);
    expect(max).toBe(42);
  });

});

describe(&quot;Test d'underscore&quot;, function() {

    var myarray;

    beforeEach(function() {
        myarray = [1, 2, 3];
    });

    it(&quot;should return 42 when asked for last item&quot;, function() {
        var res = _.last([1,2,3,42]);
        expect(res).toBe(42);
    });

    it(&quot;be true&quot;, function() {
        var res = _.first([1, 2, 3]);
        expect(res == 1).toBeTruthy();
    });

    it(&quot;should be greater than 2&quot;, function() {
        expect(3).toBeGreaterThan(2);
    });

    it(&quot;should contains 2&quot;, function() {
        expect([1, 2, 3]).toContain(2);
    });

    it(&quot;should have size of 3&quot;, function() {
        expect(myarray.length).toBe(3);
    });

    it(&quot;should not be 1&quot;, function() {
        var res = _.max([1, 2]);
        expect(res).not.toBe(1);
    })

});

describe(&quot;test with spy&quot;, function() {

    it(&quot;should spy on last&quot;, function() {
        spyOn(_, 'last');
        var res = _.last([1, 2, 3]);
        expect(_.last).toHaveBeenCalled();
        expect(res).toBeUndefined();
    });

});</pre>
<p>Vous remarquerez qu&#8217;à l&#8217;instar d&#8217;un <code>@Before</code> de JUnit, Jasmine offre la même possibilité avec <code>beforeEach</code>.<br />
De plus, Jasmine offre aussi des <a href="https://github.com/pivotal/jasmine/wiki/Spies" onclick="pageTracker._trackPageview('/outgoing/github.com/pivotal/jasmine/wiki/Spies?referer=');">fonctionnalités d&#8217;espionnage</a>.</p>
<h2>Etape #3 : Analyser son code</h2>
<p>Pour analyser le code JavaScript, nous allons utiliser le merveilleux outil qu&#8217;est <a href="http://www.sonarsource.com/" onclick="pageTracker._trackPageview('/outgoing/www.sonarsource.com/?referer=');">Sonar</a> ! Il nous faut simplement y ajouter le plugin pour le support du langage JavaScript, qui <a href="http://docs.codehaus.org/display/SONAR/JavaScript+Plugin" onclick="pageTracker._trackPageview('/outgoing/docs.codehaus.org/display/SONAR/JavaScript+Plugin?referer=');">se trouve ici</a>.</p>
<p>Dans notre pom.xml, nous devons ajouter ces quelques lignes, pour spécifier que le projet est de langage JavaScript, et indiquer la localisation de nos sources (et celles des tests) :</p>
<pre class="brush: xml;">
    &lt;properties&gt;
        &lt;sonar.language&gt;js&lt;/sonar.language&gt;
        &lt;sonar.dynamicAnalysis&gt;reuseReports&lt;/sonar.dynamicAnalysis&gt;
    &lt;/properties&gt;

    &lt;build&gt;
        &lt;sourceDirectory&gt;src/main/javascript&lt;/sourceDirectory&gt;
        &lt;testSourceDirectory&gt;src/test/javascript&lt;/testSourceDirectory&gt;
</pre>
<p>Il suffit désormais de lancer la commande <code>mvn sonar:sonar</code> pour réaliser l&#8217;analyse complète, puis de se rendre sur son serveur Sonar pour en lire les résultats !</p>
<p>Tout n&#8217;est pas encore parfait, car nous ne disposons d&#8217;aucune information propres aux tests : pourcentage de réussite, taux de couverture du code, etc.</p>
<h2>Etape #4 : Analyse de la couverture</h2>
<p>Le plugin JavaScript pour Sonar sait lire les résultats des tests exécutés par <a href="http://code.google.com/p/js-test-driver/" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/js-test-driver/?referer=');">js-test-driver</a>, une autre librairie de tests JavaScript, plus orientée TDD (<em>Tests Driven Development</em>, ou Développement piloté par les tests). Cette librairie apporte une syntaxe très proche de JUnit, en particulier concernant les assertions. En voici un exemple :</p>
<pre class="brush: jscript;">GreeterTest = TestCase(&quot;GreeterTest&quot;);

GreeterTest.prototype.testGreet = function() {
    var greeter = new myapp.Greeter();
    assertEquals(&quot;Hello World!&quot;, greeter.greet(&quot;World&quot;));
};</pre>
<p>Bon. Mais il faut tout réécrire, et perdre ce que l&#8217;on a fait avec Jasmine du coup ? Heureusement non ! Il existe en effet <a href="https://github.com/ibolmo/jasmine-jstd-adapter" onclick="pageTracker._trackPageview('/outgoing/github.com/ibolmo/jasmine-jstd-adapter?referer=');">un adaptateur</a> pour exécuter des tests Jasmine <em>via</em> js-test-driver.<br />
Bien entendu, nous aurions pu partir dès le début avec la librairie js-test-driver, et oublier Jasmine, mais ça n&#8217;aurait pas été fun !</p>
<p>Donc pour faire marcher tout cela, il faut tout d&#8217;abord copier dans un répertoire <code>lib/</code> les fichiers suivants :</p>
<ul>
<li><code>jasmine.js</code> (auparavant, il était chargé <em>via</em> le plugin Maven, que nous n&#8217;allons plus utiliser.</li>
<li><code>JasmineAdapter.js</code>, le fameux adaptateur.</li>
</ul>
<p>Puis, je crée un fichier <code>jsTestDriver.conf</code> à la racine du projet qui contient la configuration pour js-test-driver :</p>
<pre class="brush: plain;">server: http://localhost:9876

load:
  - &quot;lib/jasmine.js&quot;
  - &quot;lib/JasmineAdapter.js&quot;
  - &quot;src/main/javascript/*.js&quot;
  - &quot;src/test/javascript/*.js&quot;</pre>
<p>Ici c&#8217;est très simple, on indique le port où tournera le serveur js-test-driver, ainsi que les librairies à charger&#8230;</p>
<p>Dernière étape : modifier le pom.xml. D&#8217;abord, y supprimer les références au plugin Jasmine, devenu obsolète. Ensuite, ajouter ceci pour la dépendance vers le plugin Maven de js-test-driver :</p>
<pre class="brush: xml;">    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.googlecode.jstd-maven-plugin&lt;/groupId&gt;
            &lt;artifactId&gt;jstd-maven-plugin&lt;/artifactId&gt;
            &lt;version&gt;1.3.2.5&lt;/version&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;</pre>
<p>Puis je configure le plugin comme ceci :</p>
<pre class="brush: xml;">    &lt;build&gt;
        ...
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;com.googlecode.jstd-maven-plugin&lt;/groupId&gt;
                &lt;artifactId&gt;jstd-maven-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;port&gt;9876&lt;/port&gt;
                    &lt;browser&gt;/Applications/Firefox.app/Contents/MacOS/firefox-bin&lt;/browser&gt;
                    &lt;tests&gt;all&lt;/tests&gt;
                    &lt;config&gt;jsTestDriver.conf&lt;/config&gt;
                    &lt;testOutput&gt;target/jstestdriver&lt;/testOutput&gt;
                &lt;/configuration&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;id&gt;run-tests&lt;/id&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;test&lt;/goal&gt;
                        &lt;/goals&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;</pre>
<p>On notera que certaines informations du fichier <code>jsTestDriver.conf</code> (comme le port du serveur) sont reprises ici. On spécifie aussi le chemin vers le navigateur utilisé par js-test-driver pour exécuter ses tests (chose inutile avec Jasmine, car ce dernier ne nécessite même pas de DOM pour exécuter les tests !).<br />
Dernier point : j&#8217;ajoute le repository où se trouve le plugin js-test-driver :</p>
<pre class="brush: xml;">  &lt;repositories&gt;
        &lt;repository&gt;
            &lt;id&gt;jstd-maven-plugin google code repo&lt;/id&gt;
            &lt;url&gt;http://jstd-maven-plugin.googlecode.com/svn/maven2&lt;/url&gt;
        &lt;/repository&gt;
  &lt;/repositories&gt;
  &lt;pluginRepositories&gt;
        &lt;pluginRepository&gt;
            &lt;id&gt;jstd-maven-plugin google code repo&lt;/id&gt;
            &lt;url&gt;http://jstd-maven-plugin.googlecode.com/svn/maven2&lt;/url&gt;
        &lt;/pluginRepository&gt;
  &lt;/pluginRepositories&gt;</pre>
<p>Maintenant, pour voir si tout s&#8217;est bien passé, je vérifie que l&#8217;exécution des tests se réalise bien. J&#8217;exécute donc de nouveau la commande Maven <code>mvn clean test</code> :</p>
<pre class="brush: plain;">-------------------------------------------
 J S  T E S T  D R I V E R
-------------------------------------------

Firefox: Runner reset.
..................
Total 18 tests (Passed: 18; Fails: 0; Errors: 0) (9,00 ms)
  Firefox 9.0.1 Mac OS: Run 18 tests (Passed: 18; Fails: 0; Errors 0) (9,00 ms)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------</pre>
<p>Bravo ! C&#8217;est presque gagné ! Il ne nous reste plus qu&#8217;à pouvoir mesurer la couverture des tests. Rien de plus simple à ce stade : il suffit d&#8217;éditer le fichier <code>jsTestDriver.conf</code> et d&#8217;y ajouter les 4 lignes suivantes :</p>
<pre class="brush: plain;">plugin:
  - name: &quot;coverage&quot;
    jar: &quot;lib/coverage-1.3.4.b.jar&quot;
    module: &quot;com.google.jstestdriver.coverage.CoverageModule&quot;</pre>
<p>Je relance <code>mvn clean package sonar:sonar</code>, et l&#8217;analyse contient désormais les résultats des tests, mais aussi la couverture du code !</p>
<h2>Etape #5 : Intégration continue</h2>
<p>Lors de la présentation, j&#8217;ai manqué de temps et ai dû passé cette étape. Mais ici, rien de magique ni d&#8217;extraordinaire. En effet, comme depuis le début j&#8217;utilise des commandes Maven, les faire jouer par un serveur d&#8217;intégration continue est d&#8217;une simplicité enfantine. Je vous laisse donc le soin de jouer avec <a href="http://jenkins-ci.org/" onclick="pageTracker._trackPageview('/outgoing/jenkins-ci.org/?referer=');">Jenkins</a> ou tout autre serveur&#8230;</p>
<h2>Conclusion</h2>
<p>J&#8217;ai montré en une demi-heure environ qu&#8217;il était très simple de tester son code JavaScript, de l&#8217;analyser. Les mêmes outils sont d&#8217;ailleurs mis en oeuvre que pour le langage Java : Maven, Sonar et Jenkins.</p>
<p>Bref, il ne reste plus qu&#8217;à s&#8217;y mettre <img src='http://linsolas.free.fr/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Références</h2>
<ul>
<li><a href="https://github.com/linsolas/devoxx-chouchoutez-javascript" onclick="pageTracker._trackPageview('/outgoing/github.com/linsolas/devoxx-chouchoutez-javascript?referer=');">Projet sur GitHub</a></li>
<li><a href="http://www.slideshare.net/linsolas/devoxx-java-script1280720" onclick="pageTracker._trackPageview('/outgoing/www.slideshare.net/linsolas/devoxx-java-script1280720?referer=');">Slides sur Slideshare</a></li>
<li><a href="http://devoxx.fr/display/FR12/Chouchoutez+votre+code+JavaScript" onclick="pageTracker._trackPageview('/outgoing/devoxx.fr/display/FR12/Chouchoutez+votre+code+JavaScript?referer=');">Abstract sur le site de DevoxxFR</a></li>
<li>Vidéo Parleys (à venir)</li>
</ul>
<a href="javascript:toggleStartStop();PicLensLite.start({feedUrl:'http://linsolas.free.fr/wordpress/wp-content/plugins/wp-piclens/mrss.php?id=210'});">Start Slide Show with PicLens Lite <img src="http://linsolas.free.fr/wordpress/wp-content/plugins/wp-piclens/PicLensButton.png" alt="PicLens" width="16" height="12" border="0" align="top"></a>]]></content:encoded>
			<wfw:commentRss>http://linsolas.free.fr/wordpress/index.php/2012/04/chouchoutez-votre-code-javascript/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Calculer sa couverture de code par les tests d&#8217;intégration</title>
		<link>http://linsolas.free.fr/wordpress/index.php/2011/07/calculer-sa-couverture-de-code-par-les-tests-dintegration/</link>
		<comments>http://linsolas.free.fr/wordpress/index.php/2011/07/calculer-sa-couverture-de-code-par-les-tests-dintegration/#comments</comments>
		<pubDate>Fri, 08 Jul 2011 08:07:20 +0000</pubDate>
		<dc:creator>Romain</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[sonar]]></category>
		<category><![CDATA[tests]]></category>

		<guid isPermaLink="false">http://linsolas.free.fr/wordpress/?p=159</guid>
		<description><![CDATA[Nous allons voir ici comment, grâce à Sonar, Maven et JaCoCo nous pouvons obtenir la couverture de code par des tests d&#8217;intégration. Contexte Dans mon exemple, je me baserais sur les outils suivants : Sonar 2.8, Maven 2.2.1, Java 1.6. Au sein de l&#8217;un de mes projets, je dispose de quelques rares tests unitaires, qui [...]]]></description>
			<content:encoded><![CDATA[<p>Nous allons voir ici comment, grâce à Sonar, Maven et JaCoCo nous pouvons obtenir la couverture de code par des tests d&#8217;intégration.</p>
<p><span id="more-159"></span></p>
<h2>Contexte</h2>
<p>Dans mon exemple, je me baserais sur les outils suivants : <a href="http://www.sonarsource.org/" onclick="pageTracker._trackPageview('/outgoing/www.sonarsource.org/?referer=');">Sonar 2.8</a>, <a href="http://maven.apache.org" onclick="pageTracker._trackPageview('/outgoing/maven.apache.org?referer=');">Maven 2.2.1</a>, Java 1.6.</p>
<p>Au sein de l&#8217;un de mes projets, je dispose de quelques rares tests unitaires, qui couvre environ 7% de l&#8217;application. C&#8217;est peu. Très peu. Trop peu même.<br />
Mais nous avons également des tests d&#8217;intégration.<br />
En gros, ces tests d&#8217;intégration vont exécuter un jeu d&#8217;environ 300 fichiers d&#8217;entrée, qui seront ensuite analysés par mon application.</p>
<p>Mon but est donc de connaître, en plus de ma couverture de test par les tests JUnit, la couverture du code exécuté par mes tests d&#8217;intégration.</p>
<p>La structure de mon projet ressemble en gros à ceci :</p>
<pre class="brush: plain;">
mon-projet
  +- pom.xml (ce pom-là n'est qu'un pom d'aggrégation)
  +- parent
  |   +- pom.xml (c'est le vrai parent de tous les autres modules)
  +- module-1
  |   +- pom.xml
  +- module-2
  |   +- pom.xml
  +- ...
  +- module-tests
      +- pom.xml
      +- src/test/java/
          +- foo/bar/IntegrationTestsRunner.java
</pre>
<p><i>module-tests</i> est un module ne contenant que quelques classes de tests, en particulier <code>IntegrationTestsRunner.java</code> dont le but est d&#8217;aller lire mes fichiers de tests, et les exécuter.</p>
<p>Afin de ne pas lancer ces tests d&#8217;intégration à chaque build, nous définissons un profil Maven dans le <code>pom.xml</code> de <i>module-tests</i>, comme suit :</p>
<pre class="brush: xml;">
    &lt;profiles&gt;
        &lt;profile&gt;
            &lt;id&gt;run-it&lt;/id&gt;
            &lt;activation&gt;
                &lt;property&gt;
                    &lt;name&gt;runIT&lt;/name&gt;
                    &lt;value&gt;true&lt;/value&gt;
                &lt;/property&gt;
            &lt;/activation&gt;
            &lt;build&gt;
                &lt;plugins&gt;
                    &lt;plugin&gt;
                        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                        &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
                        &lt;configuration&gt;
                            &lt;includes&gt;
                                &lt;include&gt;**/IntegrationTestRunner.java&lt;/include&gt;
                            &lt;/includes&gt;
                        &lt;/configuration&gt;
                    &lt;/plugin&gt;
                &lt;/plugins&gt;
            &lt;/build&gt;
        &lt;/profile&gt;
    &lt;/profiles&gt;
</pre>
<p>Ce profil sera activé soit en ajoutant <code>-DrunIT=true</code> soit <code>-Prun-it</code> dans la ligne de commande Maven.</p>
<p>Avec une méthode &laquo;&nbsp;traditionnelle&nbsp;&raquo;, c&#8217;est-à-dire l&#8217;exécution de tests unitaires via Surefire, aucune couverture de code ne sera détectée, car le code exécuté par les tests d&#8217;intégration l&#8217;est sur les autres modules du projet. Or Cobertura ne va instrumentaliser que les classes du module courant et non les dépendances (i.e. <i>module-1</i>, <i>module-2</i>, etc.).</p>
<h2>Mise en place de JaCoCo</h2>
<p>Pour résoudre mon problème, je vais faire appel à <a href="http://www.eclemma.org/jacoco/" onclick="pageTracker._trackPageview('/outgoing/www.eclemma.org/jacoco/?referer=');">JaCoCo</a>, un outil de couverture de test plus performant que Cobertura. Son principal avantage est de pouvoir instrumentaliser les classes au runtime. Dans mon cas présent, JaCoCo va donc pouvoir vérifier la couverture du code sur les différents modules au moment où l&#8217;on exécute <i>module-tests</i>.</p>
<p>Avant toute chose, il va nous falloir configurer un peu notre environnement :</p>
<ul>
<li>Installer le plugin <a href="http://docs.codehaus.org/display/SONAR/JaCoCo+Plugin" onclick="pageTracker._trackPageview('/outgoing/docs.codehaus.org/display/SONAR/JaCoCo+Plugin?referer=');">JaCoCo pour Sonar</a> (à copier dans le répertoire <i>extensions/plugins</i> de son installation Sonar).</li>
<li>Une fois Sonar redémarré, penser à ajouter dans le dashboard le widget <i>IT Coverage Widget</i> (il faudra sans doute pour cela être connecté en tant qu&#8217;administrateur).</li>
<li>Télécharger l&#8217;<a href="http://www.eclemma.org/jacoco/trunk/doc/agent.html" onclick="pageTracker._trackPageview('/outgoing/www.eclemma.org/jacoco/trunk/doc/agent.html?referer=');">agent JaCoCo</a>. Pour cela, il faut récupérer le ZIP de JaCoCo <a href="http://www.eclemma.org/jacoco/" onclick="pageTracker._trackPageview('/outgoing/www.eclemma.org/jacoco/?referer=');">ici</a>, l&#8217;agent se trouvant alors dans <i>lib/jacocoagent.jar</i>.</li>
</ul>
<p>Maintenant que ceci est en place, nous allons devoir indiquer à Surefire d&#8217;utiliser un agent Java spécifique (l&#8217;agent JaCoCo).<br />
Etant donné que nous n&#8217;avons besoin de cet agent qu&#8217;au moment de l&#8217;exécution des tests d&#8217;intégration, nous le définirons que pour le profil <code>run-it</code>.<br />
Au sein du <code>pom.xml</code> parent, j&#8217;ai donc ajouté :</p>
<pre class="brush: xml;">
    &lt;profiles&gt;
        &lt;!-- Profile used to run Integration Tests. In such case, we add the Java agent for JaCoCo... --&gt;
        &lt;profile&gt;
            &lt;id&gt;run-it&lt;/id&gt;
            &lt;activation&gt;
                &lt;property&gt;
                    &lt;name&gt;runIT&lt;/name&gt;
                    &lt;value&gt;true&lt;/value&gt;
                &lt;/property&gt;
            &lt;/activation&gt;
            &lt;build&gt;
                &lt;plugins&gt;
                    &lt;plugin&gt;
                        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                        &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
                        &lt;configuration&gt;
                            &lt;argLine&gt;-javaagent:${jacoco.agent.path}=destfile=${jacoco.file.path}&lt;/argLine&gt;
                        &lt;/configuration&gt;
                    &lt;/plugin&gt;
                &lt;/plugins&gt;
            &lt;/build&gt;
        &lt;/profile&gt;
    &lt;/profiles&gt;
</pre>
<p>J&#8217;ai défini mon profil deux fois, dans le <code>pom.xml</code> parent et dans celui de <i>module-tests</i>. Nous aurions pu tout mettre dans le parent.</p>
<h2>Execution</h2>
<p>Nous allons avoir besoin d&#8217;exécuter maintenant deux commandes Maven :</p>
<ul>
<li>mvn clean install -DrunIT=true -Djacoco.agent.path=C:\dev\jacocoagent.jar -Djacoco.file.path=C:\dev\monprojet\jacoco.exec</li>
<li>mvn -Dsonar.jacoco.itReportPath=C:\dev\monprojet\jacoco.exec sonar:sonar</li>
</ul>
<p>La première ligne va activer le profil <i>run-it</i>, ce qui aura pour conséquence de lancer le tests d&#8217;intégration.<br />
On y définit les deux paramètres (<code>jacoco.agent.path</code> et <code>jacoco.file.path</code>) qui seront passés à Surefire pour définir un agent Java.</p>
<p>La seconde ligne va simplement exécuter l&#8217;analyse Sonar sur mon projet, mais en définissant le paramètre <code>sonar.jacoco.itReportPath</code> (généré lors de la première commande), cette analyse comprendra également la couverture des tests d&#8217;intégration.</p>
<p>Une fois les deux commandes exécutées, il suffit de se rendre sur son serveur Sonar pour apprécier cette nouvelle mesure de couverture de code !</p>
<p>Comme le montre <a href="http://www.sonarsource.org/measure-code-coverage-by-integration-tests-with-sonar/" onclick="pageTracker._trackPageview('/outgoing/www.sonarsource.org/measure-code-coverage-by-integration-tests-with-sonar/?referer=');">les captures d&#8217;écran sur le post du blog de Sonar à ce sujet</a>, il est possible, à l&#8217;instar de la couverture de code, de visualiser la couverture de code de tests d&#8217;intégration directement dans la fenêtre de visualisation du code source d&#8217;une classe.</p>
<p><img src="http://linsolas.free.fr/wordpress/wp-content/uploads/it-code-coverage.jpg"/></p>
<a href="javascript:toggleStartStop();PicLensLite.start({feedUrl:'http://linsolas.free.fr/wordpress/wp-content/plugins/wp-piclens/mrss.php?id=159'});">Start Slide Show with PicLens Lite <img src="http://linsolas.free.fr/wordpress/wp-content/plugins/wp-piclens/PicLensButton.png" alt="PicLens" width="16" height="12" border="0" align="top"></a>]]></content:encoded>
			<wfw:commentRss>http://linsolas.free.fr/wordpress/index.php/2011/07/calculer-sa-couverture-de-code-par-les-tests-dintegration/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
