Fitnesse, Maven, Sonar : comment faire monter la mayonnaise

Publié le 20/09/2011, par Etienne Charignon dans Agile, Java, Valtech | 8 Commentaires

Comme je le disais récemment dans un tweet, j’ai finalement réussi à configurer le build Maven pour que la couverture du code par les tests, affichée dans le dashboard Sonar, tienne compte des tests Fitnesse.

J'ai finalement réussi à obtenir de #sonar de prendre en compte des tests #Fitnesse dans la mesure de la couverture.

En voila un sujet pointu ! Pourtant, à la suite de ce tweet, plusieurs personnes m’ont demandé une version longue. Je vais donc essayer dans ce message de décrire en détail la configuration complète que nous avons mise en place. J’espère que vous saurez comprendre le fonctionnement de cette solution, pour ensuite l’adapter à votre situation personnelle. Pour ceux qui ne comprennent pas les 3 premiers mot du titre, vous pouvez si vous le désirez vous plonger dans une bonne demi-heure de perplexité et lire la suite de ce message.

Intégration de Fitnesse dans le build Maven

Nous utilisons Fitnesse comme base de documentation pour notre projet. Le wiki contient toute sorte de documentation, technique ou non, concernant le projet ainsi que, bien entendu, tous les spécifications fonctionnelles automatisées.

Remarque : dans la suite de cet article, je parle indifféremment de spécifications fonctionnelles automatisées, de spécifications exécutables ou de tests Fitnesse. Toutes ces appellations désigne la même chose.

Fitnesse n’utilise pas de base de données, mais une hiérarchie de répertoires et de fichiers textes qui représentent les pages du wiki. L’intégralité du projet Fitnesse est contenu dans un répertoire qui est installé dans la gestion de configuration (sur notre projet, nous avons utilisé Git). Cette solution a l’avantage de permettre à tous les développeurs de l’équipe d’avoir une version complète du site en local sur leur poste. Ils peuvent ainsi exécuter les spécifications localement sur leur poste, avant de soumettre le code et les pages Fitnesse correspondantes à l’intégration continue.

Au niveau du build Maven, nous avons dédié un module à Fitnesse. Voici un extrait du répertoire racine de notre projet :

Vous voyez que dans notre répertoire lcwp-fitnesse (lcwp est le nom du projet) se trouve un fichier pom.xml. Le répertoire src ne contient pas de code. Toutes les pages du wiki sont dans le répertoire FitNesseRoot. Vous voyez aussi le fichier fitnesse.jar qui est l’exécutable proprement dit. Bien qu’il ne soit pas recommandé de mettre des binaires en gestion de configuration, nous faisons une exception pour celui-ci car c’est vraiment plus pratique comme ça.

Le plug-in Maven pour auto-générer le classpath utilisé par Fitnesse

Il s’agit du plugin maven-fitnesse-cpgen-plugin qui se trouve être un plugin développé par Valtech. Pour la documentation, suivez le lien suivant : http://source.valtech.com/maven-sites/maven-fitnesse-cpgen-plugin/usage.html

Installation du plugin

Pour utiliser ce plugin il suffit de référencer le dépôt Maven de Valtech (voir le lien ci-dessus) dans votre fichier setting.xml et d’ajouter la section XML suivante dans le fichier lcwp-fitnesse/pom.xml

<plugin>
	<groupId>com.valtech.source.maven</groupId>
	<artifactId>maven-fitnesse-cpgen-plugin</artifactId>
	<version>1.0</version>
	<configuration>
		<fitnesseRoot>${basedir}/FitNesseRoot</fitnesseRoot>
	</configuration>
	<executions>
		<execution>
			<phase>package</phase>
			<goals>
				<goal>gencp</goal>
			</goals>
		</execution>
	</executions>
</plugin>

Contenu de la page “root”

Vous devez ensuite modifier le fichier lcwp-fitnesse/FitNesseRoot/content.txt pour qu’il contienne exactement le texte suivant. Ce fichier correspond à la page “root” du site (http://localhost:9090/root) :

!define TEST_SYSTEM {slim}
 
!include ProjectPath
 
# begin of maven classpath
# end of maven classpath

La première ligne ne concerne pas notre sujet. Elle indique que tous nos pages Fitnesse seront exécutés avec le moteur SLIM.

Le plug-in ajoutera tout le classpath maven, dont les dépendances sont décrites dans le pom.xml du module lcwp-fitnesse, entre les deux dernières lignes du fichier.

La page ProjectPath contient des chemins spécifiques qui ne seront pas ajoutés par le plugin et que nous devons donc ajouter nous même. J’en reparlerai plus tard. Elle contient une partie de l’astuce ultime de notre solution.

Problème : ce fichier lcwp-fitnesse/FitNesseRoot/content.txt sera modifié à chaque build et le classpath inséré par Maven sera potentiellement différent pour chaque poste de développeur. Ce fichier ne peut donc pas être géré dans Git (il faut l’ajouter au fichier .gitIgnore).

Astuce : Pour que chaque développeur ne soit pas obligé de créer ce fichier sur son poste, nous avons ajouté la configuration suivante dans notre pom.xml :

<plugin>
	<artifactId>maven-antrun-plugin</artifactId>
	<version>1.6</version>
	<executions>
		<execution>
			<phase>generate-sources</phase>
			<goals>
				<goal>run</goal>
			</goals>
			<configuration>
				<tasks>
					<echo>Fitnesse root</echo>
					<copy file="src/test/resources/fitnesseRootContent.txt"
						tofile="${project.basedir}/FitNesseRoot/content.txt" overwrite="true" />
				</tasks>
			</configuration>
		</execution>
	</executions>
</plugin>

Le contenu standard du fichier lcwp-fitnesse/FitNesseRoot/content.txt est enregistré dans le fichier src/test/resources/fitnesseRootContent.txt qui lui est géré dans Git. Ce fichier est recopié au moment du build, juste avant l’éxécution du plugin maven-fitnesse-cpgen-plugin.

Propriétés de la page “root”

Enfin, vous devez changer une propriété de la page root pour quelle soit de type “Suite”. C’est nécessaire pour que le plugin maven trouve la page. Vous pouvez le faire par le wiki en vous rendant à l’URL http://localhost:9090/root, en cliquant sur le bouton “Properties” et en sélectionnant “Suite” pour la propriété “Page type”. Alternativement, vous pouvez aussi directement modifier le fichier lcwp-fitnesse/FitNesseRoot/properties.xml pour qu’il contienne la balise <Suite/>. Voici par exemple le contenu de notre fichier :

<?xml version="1.0"?>
<properties>
	<Edit/>
	<Files/>
	<Help></Help>
	<Properties/>
	<RecentChanges/>
	<Refactor/>
	<Search/>
	<Suite/>
	<Suites></Suites>
	<Versions/>
	<WhereUsed/>
</properties>

Le contenu de la page ProjectPath

Le plugin décrit précédemment nous a permis de gérer simplement le gigantesque classpath des dépendances vers les composants externes de notre projet. C’est la page ProjectPath qui contient les chemins vers le code proprement dit de notre projet. Voici son contenu dans notre cas :

!path ../lcwp-web/target/generated-classes/cobertura
!path ../lcwp-web/target/classes
!path ../lcwp-core/target/classes
!path ../lcwp-integration/target/classes
!path ../lcwp-web/target/test-classes
!path ../lcwp-test-support/target/classes

Le chemin est indiqué relativement au répertoire lcwp-fitnesse, c’est pourquoi tout les chemins sont précédés de “../“.

Et voilà la solution du problème : Pour que la couverture des tests affichée dans le dashboard Sonar tienne compte des tests Fitnesse, il faut que ces derniers soit exécutés sur le code instrumenté par cobertura. Le code instrumenté est généré dans le répertoire target/generated-classes/cobertura. Avec la première ligne de notre fichier nous obtiendrons donc la couverture du code du module lcwp-web.

En développement, le répertoire generated-classes/cobertura est vide et c’est la ligne suivante qui permettra de trouver le code du module lcwp-web.

Pour information, nous avons mis le code des fixtures Fitnesse dans l’arborescence de tests du module lcw-web. C’est donc la ligne ../lcwp-web/target/test-classes qui permet de le trouver.

L’exécution des spécifications par Maven

Tout ce que je viens d’expliquer nous permet d’exécuter les spécifications depuis le wiki.

En local sur le poste d’un développeur, vous devez démarrez Fitnesse avec les commandes suivantes :

cd lcwp-fitnesse
java -jar fitnesse.jar -p 9090 -e 0

Ensuite, vous pouvez vous rendre sur le site à l’URL : http://localhost:9090/FrontPage, naviguer jusqu’à la page de spécification qui vous intéresse et cliquer sur le bouton [Test] (dans la colonne de gauche) pour l’exécuter.

Mais ce que nous voulons, c’est que toutes les spécifications Fitnesse soit exécutées lors du build maven, c’est à dire à l’exécution de la commande mvn clean package

Fitnesse vous propose une ligne de commande pour exécuter tous ses tests :

java -jar fitnesse.jar -c DetailedSpecifications?suite&amp;format=text

DetailedSpecifications est la page du wiki, racine de toutes nos spécifications. Elle est de type “Suite”.

Nous avons tout d’abord ajouté au build un appel à cette commande en utilisant le plugin ant de maven, mais il nous a paru finalement plus simple de faire un appel système dans un tests unitaire jUnit. En effet, la seule façon de savoir si les tests se sont exécutés correctement est d’analyser la sortie standard, le code de retour de cette commande (code de retour de la JVM en fait) étant zéro dans tous les cas. Il est nettement plus facile d’analyser cette sortie en java qu’avec la configuration XML du plug-in ant de maven.

Ce test unitaire doit faire parti des tests du module lcwp-web (c’est la couverture sur ce module qui nous intéresse). Il doit donc se trouver dans l’arborescence lcwp-web/src/test/java/...

J’ai posté le code sur GitHub à l’URL suivante :
https://github.com/etienneCharignon/FitnesseTools/blob/master/fitnesse/tools/FitnesseTest.java

Conclusion

Une belle image vaut mieux qu’un long discours. Nous sommes passés d’un peu plus de 25% à 65,20 % :

Couverture Sonar finale


La marmite de la rentrée avec les Duchess

Publié le 15/09/2011, par Amira Lakhal dans Événements, Java, Valtech | Ajouter un commentaire

Valtech accueille la 3ème édition de La Marmite, le lundi 19 Septembre 2011 à partir de 19h30 au 103, rue Grenelle, Paris.

Logo de La MarmiteLa Marmite est un rendez vous mensuel organisé par Duchess France qui permet d’échanger sur les meilleurs outils et recettes de développement.

Les sessions sont composées de 2 tracks en parallèle : un atelier et un Open Space :
  • L’Atelier portera sur le thème Node.js . Il sera animé par Olivier Bazoud, Mathilde Lemée et Romain Maton . Il s’agit d’ un exercice pratique donc il faudrait amener un pc Linux ou MaxOSX. La première demi-heure sera réservée à la théorie, les deux heures suivantes à la pratique en pair programming.
  • L’Open Space est un espace de discussion structuré. Les participants proposent des sujets, votent puis discutent dans des sessions de 20 à 30 mn. A la fin le porteur du sujet fait un bilan et rédige un résumé. Cette fois ci Alexandre Bertails du W3C viendra refaire une partie de sa présentation sur les typages dans les langages de programmation et parler de Scala et Web Sémantique.

N’hésitez pas à vous inscrire à l’évènement via Eventbrite!

Venez améliorer vos connaissances