Skip navigation

I.            Introduction

Nous allons voir dans ce résumé de blogue une façon innovante de créer, exécuter, lire, et organiser ses tests d’acceptation. Les tests d’acceptation permettent de valider un logiciel vis-à-vis du client en se basant sur ses spécifications (plus communément appelées « les spécs »). Les tests d’acceptation viennent en complément des tests unitaires. Alors que les tests unitaires répondent à la question « est-ce que j’ai écris le code correctement ? », les tests d’acceptation répondent à la question « est que j’ai écris le bon code ? » (c’est-à-dire ce que veut le client). Il n’est pas toujours facile de créer des tests lisibles par un client non informaticien et c’est à ce moment là que Fitnesse[1] vient à notre secours.

Cet article est aussi disponible en version PDF, il est basé sur l’article « Acceptance Testing with FitNesse »[2].

II.            Qu’est ce que Fitnesse

Les tests d’acceptation sont basés sur les spécifications du logiciel, mais les spécifications c’est souvent ça : « Pas assez précises ! Jamais à jour ! Trop volumineuses ! Trop détaillées ! Trop techniques ! Pas assez techniques ! Trop éclatées ! Quelles specs ? Pas disponibles ! Pas stables ! » Nous allons donc voir en quoi Fitnesse pourrait remédier à ces problèmes.

Fitnesse est un outil collaboratif pour écrire et exécuter des tests d’acceptation. Les tests sont écrits dans un langage Wiki ce qui demande peu d’apprentissage (en théorie), et rend possible l’écriture des tests/specs par des non informaticiens (le client par exemple). D’autre part, Fitnesse est un serveur web, il ne demande aucune configuration, il n’y a qu’à le lancer, écrire les tests, et les exécuter.

Workflow FitnesseFigure 1 - Workflow du framework

Voici un schéma descriptif de Fitnesse. On constate que Fitnesse peut fonctionner avec deux systèmes de test différents, soit FIT (ancien système), soit SLIM (nouveau système). Dans la suite de ce tutoriel je décrirai comment utiliser Fitnesse avec SLIM qui est système le plus récent. Les cas d’utilisation sont donc écrits dans des pages Wiki, puis interprétés par un des deux systèmes de test, qui à son tour appellera les Custum Fixtures (code de liaison), qui appelleront à leur tour le SUT (System Under Test : Système à tester).

III.            Fitnesse par l’exemple

Dans cette partie je vais vous montrer un exemple de base avec Fitnesse en espérant qu’il saura vous convaincre d’aller plus loin avec cet outil. Commençons par télécharger Fitnesse depuis le site officiel[3].

Pour lancer Fitnesse vous devez entrer la commande suivante dans la console de votre système d’exploitation (assurez vous d’avoir Java 6 d’installé), en replaçant #num_port par le numéro du port sur lequel vous souhaitez démarrer l’application :

Java –jar fitnesse.jar –p #num_port


Lors du premier démarrage, Fitnesse doit s’installer, cela prendra quelques minutes, les prochaines fois le démarrage ne prendra que quelques secondes. Vous pouvez désormais accéder à Fitnesse depuis votre navigateur  à cette adresse : http://localhost:#num_port/

Nous allons maintenant créer une nouvelle page pour écrire les tests de notre système à tester. Ce système sera une calculatrice,  appelons donc la page « CalculatorTests »[4]. Pour la créer suivez l’instruction en anglais de la page d’accueil. Ajoutez à cette page le contenu suivant :

!contents -R2 -g -p -f -h
Définit que le test doit être exécuté avec SLIM

!define TEST_SYSTEM {slim}


Créez une nouvelle page comme enfant de celle-ci en cliquant sur le bouton « add child », nommez cette page « CalculatorTest », et cocher le bouton radio « Test » lors de la création. Une fois la page créée, ajoutez y les tests suivants :

|Add two number                          |
|first int|second int|result of addition?|
|0        |1         |1                  |
|2        |0         |2                  |
|2        |3         |5                  |

|Subtract an integer to another                   |
|int to be subtracted|minus|result of subtraction?|
|0                   |1    |-1                    |
|4                   |2    |2                     |
|3                   |1    |2                     |

Comme vous pouvez le constater les spécifications s’écrivent sous forme de tableau. La première ligne du tableau permet de décrire le test contenu dans le tableau, et sera aussi le nom de la Custum Fixture. Les variables d’entête permettent de définir les paramètres d’entrés (variable non marquées par un « ? »), et les paramètres de sorties (variables marquées par un « ? »).

NB : Dans la pratique les classes se trouvent dans des packages il faudra donc préciser au dessus des tests les packages dans lesquels se trouvent les Fixtures.

Nous allons maintenant créer un projet Java dans Eclipse qui jouera le rôle du système à tester. Appelons le projet « Calculator ». Créez une classe dans ce projet nommée « Calculator », et ajoutez y le code suivant :

public class Calculator {
 
  public int add(int a, int b) {
    return a + b;
  }
 
  public int minus(int intToBeSubtracted, int minus) {
    return intToBeSubtracted + minus;
  }
}


Notre calculatrice peut donc ajouter ou soustraire des entiers deux à deux. J’ai très volontairement introduit une erreur dans l’opération minus afin que les tests échouent pour cette fonction.

Nous allons maintenant créer les Custum Fixtures qui servent à faire le lien entre le code Wiki et le code du système à tester. Il y a certaines conventions à respecter pour l’écriture de ces classes pour qu’elles correspondent aux spécifications. Créez les deux classes suivantes :

public class AddTwoNumber {
  private int firstInt;
  private int secondInt;
 
  private Calculator calculator;
 
  public AddTwoNumber() {
    calculator = new Calculator();
  }
 
  public void setFirstInt(int firstInt) {
    this.firstInt = firstInt;
  }
 
  public void setSecondInt(int secondInt) {
    this.secondInt = secondInt;
  }
 
  public int resultOfAddition() {
    return calculator.add(firstInt, secondInt);
  }
}
 
public class SubtractAnIntegerToAnother {
  private int intToBeSubtracted;
  private int minus;
 
  private Calculator calculator;
 
  public SubtractAnIntegerToAnother() {
    calculator = new Calculator();
  }
 
  public void setIntToBeSubtracted(int intToBeSubtracted) {
    this.intToBeSubtracted = intToBeSubtracted;
  }
 
  public void setMinus(int minus) {
    this.minus = minus;
  }
 
  public int resultOfSubtraction() {
    return calculator.minus(intToBeSubtracted, minus);
  }
}

Il existe des correspondances entre le code Wiki et le code Java afin que Fitnesse puisse effectuer les appels Java en fonction du code Wiki, voici les conversions qui sont faites et qui sont donc à respecter :

Wiki

Java

Add two number

public Class AddTwoNumber{ … }

first int

public void setFirstInt(int firstInt) {…} //peu importe le nom du paramètre.

result of addition?

public void resultOfAddition() {…}


Il en va de même pour les autres entêtes.

Il reste une dernière étape de configuration avant de pouvoir exécuter les tests c’est de préciser dans la page de configuration de nos test le chemin vers les fichiers binaires de notre système à tester. Le code de la page CalculatorTests devient donc :

!contents -R2 -g -p -f -h
 
Définit que le test doit être exécuté avec SLIM
!define TEST_SYSTEM {slim}
 
À adapter en fonction de chacun. Peut être un chemin relatif par rapport à la racine de Fitnesse.
!path /Users/Romain/Documents/eclipse/Laval/calculator/bin

 

Vous pouvez maintenant vous rendre à la page CalculatorTest et cliquer sur le bouton « Test », vous devriez obtenir le résultat suivant :

Résultats des testsFigure 2 - Résultats de des tests

Les tests qui passent sont surlignés en vert alors que ceux qui échouent sont surlignés en rouge. En lisant les résultats on se rend donc compte qu’il y a un problème avec la fonction de soustraction. Il ne vous reste plus qu’à corriger cette fonction pour faire passer tous les tests.

 IV.            Avantages et inconvénients

a.      Avantages

Les avantages d’utiliser un outil comme Fitnesse sont multiples :

  • Fitnesse est un outil collaboratif. D’un coté, les analystes et les clients peuvent écrire la spécification du logiciel dans Fitnesse à l’aide du code Wiki, de l’autre coté les développeurs et les testeurs peuvent écrire les Custum Fixtures pour faire la liaison entre les spécifications et le système à tester.
  • Les tests sont lisibles par tous. Analystes, clients, développeurs, …
  • Il n’y a pas de redondance d’information, les spécifications sont les tests.
  • Tout ceci étant basé sur un serveur, la spécification ainsi que les tests sont donc toujours à jour, et toujours disponibles.
  • Fitnesse gère les versions. Il est possible de revenir en arrière sur un test.
  • Les tests ne sont pas exécutés via l’interface du système à tester, donc même si l’interface change, les tests n’ont pas besoin de changer.

b.     Inconvénient

Il existe tout de même des inconvénients à Fitnesse :

  • L’interface est assez laide, et vieillotte.
  • Il pourrait être pratique de spécifier un certain nombre de paramètre via l’interface au lieu que ce soit fait dans du code Wiki (Le type de test (FIT ou SLIM), le path pour les fichiers binaires, le path pour les JARs externes, …).
  • Il n’y a pas d’éditeur WYSIWYG intégré à Fitnesse pour l’écriture des tests. Il existe cependant un plugin-in[5] plus ou moins buggé pour remédier à cela.
  • On fait souvent des fautes de frappe entre le nom des entêtes dans le Wiki et le nom des fonctions ou des classes dans le code JAVA.
  • L’intégration avec maven est très délicate. Il n’y a pas de solution « officielle », chacun y va de sa solution plus ou moins bancale.

    V.            Mon avis

Fitnesse est un outil intéressant qui permet de sortir les tests du code. Les tests sont donc lisibles par des non informaticiens. Ces derniers peuvent même contribuer à l’écriture des tests. Dans la pratique cela reste quand même compliqué je trouve, l’écriture des tests n’est pas aussi aisée que cela puisse paraître. Il y a beaucoup de types de table de test, et on n’est pas loin de faire programmation quand on écrit les tests.

Pour finir je trouve aussi qu’il ne peut pas remplacer les « vraies » spécifications, car la mise en page est trop limités. La lecture des tests est correcte, mais pas exceptionnelle. Je trouve donc qu’il serait intéressant d’essayer d’autres outils similaires à Fitnesse pour en trouver un plus poussé que celui-ci.

 VI.            Aller plus loin

J’ai décris ici un test très basique. Il est possible d’écrire de nombreux types de tests sous Fitnesse. Je vous laisse consulter le guide utilisateur pour se faire. Sachez toute de même qu’il est possible par exemple de tester le contenu de listes, ou bien encore écrire des scénarios.

Il est possible d’intégrer Fitnesse avec le serveur d’intégration continue Hudson. Pour se faire vous pouvez suivre ce tutoriel[6]. Hudson se chargera de démarrer Fitnesse, d’exécuter les tests, et d’arrêter Fitnesse. Vous pourrez ensuite consulter les résultats des tests dans Hudson.

Nous avons parlé pendant le cours de Selenium pour tester les interfaces graphiques, sachez qu’il est possible de coupler Fitnesse avec ce dernier. Vous pouvez par exemple suivre ce tutoriel[7] pour faire fonctionner ces deux outils ensemble.

Il existe aussi des plugins Eclipse qui permettent de lancer Fitnesse, d’exécuter les tests, et de lire les résultats à l’intérieur d’Eclipse. En voici un[8] parmi ceux qu’il existe. Je ne l’ai pas essayé moi-même, mais il semble être celui le plus évolué.

VII.            Outils similaires

Fitnesse a été le précurseur dans ce domaine mais il existe maintenant d’autres outils similaires :

  • Concordion[9] : Les tests sont écris dans un langage courant et peuvent être consulté via  un navigateur Internet. Les développeurs peuvent récupérer des variables des tests grâce à des marqueurs HTML qu’ils ajoutent sur des mots précis, ce qui est invisible quand on consulte les tests par un navigateur Internet.

Vu du code HTML :

<html xmlns:concordion="http://www.concordion.org/2007/concordion">
    <body>
        <p concordion:assertEquals="getGreeting()">Hello World!</p>
    </body>
</html>


Vu dans un navigateur :

Vu dans le navigateur

Vu de la Fixture Java :

public class HelloWorldTest extends ConcordionTestCase {
 
    public String getGreeting() {
        return "Hello World!";
    }
}
  • Green Pepper[10]  (outil payant // version d’essaie de 30 jours) : Le principe est le même que Fitnesse, il permet d’écrire des tests sur un serveur Wiki, et d’écrire des fixtures pour faire la liaison entre les tests et le système à tester.

    Le lien entre le code wiki et les fonctions Java ne se fait plus sur les noms des entêtes mais par expressions régulières ce qui évite les noms de fonction Java à rallonge :

{{greenpepper-import parameter="fr.xebia.batch.fixture"/}}
|= Scenario |= XebianScenario
|= lancer le batch xebia avec le fichier toto.xml
|= vérifier que les 2 affaires ont été créées

 

public class XebianScenarioFixture {
    int resultingAffaire;
    @Given("lancer le batch (\\w+) avec le fichier (\\w+\\.xml)")
    public void launch(String batchName, String fileName){
        System.out.println(batchName);
        System.out.println(fileName);
        //Appeler notre batch et stocker le nombre d'affaire créées dans resultingAffaire
    }
    @Check("vérifier que les (\\d+) affaires ont été créées")
    public boolean verifyResult(int expectedAffaire){
        return expectedAffaire == resultingAffaire;
    }
}

Références

Premiers pas avec GreenPepper XWiki : http://blog.xebia.fr/2010/04/09/premiers-pas-avec-greenpepper-xwiki/

Ruining your Test Automation Strategy : http://blog.objectmentor.com/articles/2009/09/29/ruining-your-test-automation-strategy

Fitnesse, un Wiki pour vos tests fonctionnels : http://www.dotnetguru.org/articles/dossiers/fitnesse/article.htm