Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Concordion, les tests d'acceptation faciles

Un "test d'acceptation" est un test rédigé par, ou en coopération avec la MOA. C'est une véritable spécification exécutable, qui est décrite dans un format humainement lisible. Le but recherché est d'extraire les algoritmes métiers du code, afin de les rendre visibles par tous les acteurs du projet - MOA, développeurs, testeurs, éventuellement les utilisateurs...

Les tests d'acceptation encouragent la "spécification par l'exemple" : la fonctionnalité développée est encadrée par des exemples décrivant les cas nominaux, les cas particuliers, les exceptions, etc. Les tests s'assurent ensuite que le comportement attendu est respecté.

Plusieurs outils existent, comme FitNesse, Cucumber (Ruby), RobotFramework (Python), JBehave (Java)... Concordion se démarque du lot par son extrême simplicité de mise en oeuvre car il s'appuie sur JUnit, et ne nécessite aucun serveur externe ni langage exotique.


concordion-logo.png

Concordion en pratique

Concordion est une extension de JUnit (c'est un Runner spécial). Il suffit de placer quelques jars dans le classpath en plus de JUnit, et le tour est joué.

Ensuite, pour développer un test, il faut :

  • Ecrire une page HTML décrivant les spécifications, sous la forme de texte libre ou de tableaux.
    Dans l'exemple que nous verrons plus loin, nous utiliserons un tableau dont les deux premières colonnes seront les paramètres d'entrée de la méthode testée, et la troisième colonne le résultat attendu.
  • Instrumenter la page HTML avec des instructions Concordion, qui se présentent sous la forme d'attributs de balise html (ex:concordion:assertEquals(#param1), concordion:set(#param1)...). Ces instructions pilotent une classe de test appelée fixture.
  • Ecrire la classe de fixture, qui fait le pont avec les classes et méthodes testées. Cette classe ressemble beaucoup à un test JUnit standard, en ce sens qu'elle a la charge d'initialiser l'environnement et d'appeler les méthodes à tester.

Prenons un exemple simple : nous voulons tester une méthode qui ajoute deux nombres.

  • Premièrement, écrivons notre page HTML de spécification. Encore une fois, le format est libre, et nous pouvons utiliser par exemple des phrases ou paragraphes entiers tirés d'un document Word ou d'un simple email... Pour l'exemple, nous utiliserons quelques phrases en anglais, ainsi qu'un tableau.
  • Ensuite, instrumentons cette page avec des propriétés Concordion, pour lui indiquer où se trouvent les données intéressantes, et quelle méthode appeler sur la classe de fixture :


concordion-before.png

One and One :
<span concordion:set="#val1">1</span> and
<span concordion:set="#val2">1</span> is
<span concordion:assertEquals="add(#val1, #val2)">2</span>
<br/>

Zero changes nothing :
<span concordion:set="#val3">0</span> +
<span concordion:set="#val4">1</span> =
<span concordion:assertEquals="add(#val3, #val4)">1</span>
<br/>

<table concordion:execute="#somme = add(#op1, #op2)">
<tr>
    <th>Description</th>
    <th concordion:set="#op1">Value 1</th>
    <th concordion:set="#op2">Value 2</th>
    <th concordion:assertEquals="#somme">Sum</th>
</tr>
<tr>
    <td>Zero</td>
    <td>0</td>
    <td>0</td>
    <td>0</td>
</tr>
<tr>
    <td>Basic addition</td>
    <td>5</td>
    <td>3</td>
    <td>8</td>
</tr>
<tr>
    <td>Negative numbers</td>
    <td>4</td>
    <td>-1</td>
    <td>3</td>
</tr>
</table>
  • Enfin, écrivons la classse de fixture. Dans l'exemple ci-dessous, le résultat est calculé par la méthode add() elle-même, mais dans un véritable test, un service métier serait appelé.
@RunWith(ConcordionRunner.class)
public class AddSpecTest {
    public int add(int val1, int val2) {
        // You should call a real business service here !
        return val1 + val2;
    }
}

Il ne reste plus qu'à lancer ce test comme n'importe quel test JUnit (son résultat influencera la barre verte/rouge de la même manière, ainsi que le compte des tests passés/ratés dans Jenkins, Maven...).

Concordion va dupliquer la page HTML et colorer les tests en vert ou rouge, en fonction du résultat des tests. Si un test ne passe pas, la valeur attendue et la valeur réelle sont indiquées. Et en cas d'exception, une zone dépliable permettra de voir la stacktrace associée. Pratique !


concordion-after.png concordion-error.png

Bonnes pratiques

Encore une fois, les tests Concordion (HTML + fixtures) ne sont ni plus ni moins que des tests JUnit déguisés ; ils sont donc naturellement placés avec les autres tests unitaires ou d'intégration.

Par contre, il faut faire attention à respecter une certaine nomenclature : pour tester la classe Foo, on produira une page HTML FooSpec.html et une classe FooSpecTest.java. Il est important de respecter ce nommage, car Concordion se base dessus pour faire la correspondance entre les différents éléments.

Enfin, veillez à réserver les tests d'acceptation aux tests à forte composante métier. Les tests d'algorithmes techniques ou de méthodes utilitaires devraient être implémentés sous forme de tests JUnit "normaux".

Intégration à Jenkins

Jenkins dispose d'un plugin Concordion Presenter, qui ajoute un lien dans la barre latérale des builds. Malheureusement, sa version actuelle ne génère pas de page d'index, ce qui le rend inutilisable en pratique.

J'ai soumis un patch (GitHub : OlivierCroisier/concordionpresenter-plugin) qui corrige ce problème ; il est en attente de ''pull' depuis un certain temps. Si vous voulez toutefois en bénéficier, vous pouvez utiliser le .hpi disponible en pièce jointe de ce billet.


Concordion-link.png concordion-index.png

Conclusion

Concordion est un framework très simple à mettre en oeuvre, qui permet de rendre visible des règles et algorithmes métiers trop souvent noyés dans le code.

Des tests d'acceptation bien écrits peuvent servir de spécifications (exécutables qui plus est), d'exemple, et de référence pour tous les acteurs du projet. Ils permettent également, dans certains cas, de sauvegarder et conserver des "spécifications" reçues par mail ou sur un post-it. Ce sont donc d'excellents compléments aux tests techniques classiques.

En conclusion, je vous encourage à essayer !
Le risque est nul pour le projet, le framework n'étant pas invasif. Et qui sait, cela sera peut-être une excellente occasion pour impliquer les MOA et travailler conjointement sur l'amélioration des spécifications !


Commentaires

1. Le jeudi 22 septembre 2011, 01:01 par Grégory Boissinot

Concernant l'intégration dans Jenkins, le plugin JUnit Attachments (https://wiki.jenkins-ci.org/display...) devrait suffire.

2. Le dimanche 25 septembre 2011, 17:53 par Piwaï

Intéressant !

J'ai quand même un doute sur l'adoption de l'outil par des MOA. Éditer du HTML n'est pas à la portée de tout le monde...

3. Le lundi 26 septembre 2011, 21:23 par joseph

L'idée n'est pas que la MOA édite de l'html, mais plutôt qu'elle décrive dans son vocabulaire les règles métiers puis qu'elle associe des exemples correspondant (toujours dans le langage du domaine).

La mise en musique est ensuite du ressort de l'informatique, bien sûr, mais on a alors un référentiel commun testé automatiquement au cours du temps. Plus besoin de chercher dans le code une règle métier pour tenter ensuite de la traduire à l'utilisateur: tout est là, en un endroit unique.

On parle d'ailleurs de "living documentation" pour ce genre de techniques, vu que pour une fois on est assuré que la doc est toujours conforme au code (même si bien sûr ces tests ne sont pas suffisants, juste sacrément nécessaire).

++
joseph

4. Le mercredi 28 septembre 2011, 10:51 par François Petitit

Bonjour et merci pour cet article.

J'ai utilisé Concordion sur un projet sur lequel Fitnesse était d'abord pressenti.
Quand nous avons constaté que la MOA n'écrirai jamais elle-même ses tests dans Fitnesse (pour diverses raisons dont le manque de temps pour apprendre à l'utiliser), et que Concordion était beaucoup plus efficace pour les développeurs, nous avons opté pour Concordion.

Au final il a très bien marché, ce fut un bon choix.
Mais effectivement si on peut entraîner la MOA à écrire elle-même les tests d'acceptance, alors Concordion ne convient plus.

5. Le mercredi 12 octobre 2011, 15:38 par François Petitit

Et merci pour le plug-in, je l'ai installé sur mon nouveau projet et ça marche :)

6. Le mercredi 12 octobre 2011, 16:07 par Olivier Croisier

Cool :)

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.