Vos recrutements informatiques

700 000 développeurs, chefs de projets, ingénieurs, informaticiens...

Contactez notre équipe spécialiste en recrutement

Tutoriel pour tester une webapp à l'aide de FluentLenium, en 5 minutes

Thierry

Lorsque vous développez un site Web, vous avez besoin de tester que les pages fonctionnent. Et ces tests doivent pouvoir s'automatiser lorsque le site grossit. L'outil le plus populaire est Selenium mais ce dernier n'est pas des plus simples à prendre en main. Heureusement, une bibliothèque française nommée FluentLenium simplifie le travail. C'est ce que nous allons voir dans cet article. 1 commentaire Donner une note à l'article (5)

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Lorsque vous développez un site Web, vous avez besoin de tester que les pages fonctionnent. Et ces tests doivent pouvoir s'automatiser lorsque le site grossit. Dans l'article Tutoriel sur le test d'applications Web avec Selenium, Denis Thomas nous présentait Selenium, l'outil Java le plus utilisé pour tester les IHM. Or Selenium n'est pas si simple à prendre en main.

Dans cet article, nous allons utiliser FluentLenium qui, comme son nom l'indique, permet de simplifier l'utilisation de Selenium tout en proposant de bonnes pratiques.

FluentLenium est une bibliothèque française : cocorico. Elle a été développée par Mathilde Lemée, qu'on croise régulièrement dans des grandes conférences comme Devoxx

I-A. À propos

Découvrir une technologie n'est pas chose facile. En aborder plusieurs d'un coup l'est encore moins. Partant de ce constat, cet article a été écrit pour aller à l'essentiel. Les points importants sont présentés dans le corps de l'article et les éléments secondaires sont expliqués en annexe.

I-B. Avant de commencer

Pour écrire ce tutoriel, j'ai utilisé les éléments suivants :

  • Java JDK 1.6.0_24-b07 ;
  • Eclipse Indigo 3.7 JEE 64b ;
  • Maven 3.0.3 ;
  • Tomcat 7.0.35 ;
  • Pretty Faces 3.3.2 ;
  • JUnit 4.11 ;
  • FluentLenium 0.9.1.

I-C. Mises à jour

xxx: création

II. Découverte du projet d'exemple

II-A. Télécharger, installer et importer le projet d'exemple

Pour commencer, je vous propose de télécharger le fichier Zip« fibo-webapp-fluentlenium.zip », contenant un projet Java-Maven d'exemple (une mini webapp) qui va nous servir de support visuel pour les fonctionnalités présentées dans la suite de cet article.

Cette webapp est celle que nous avions développée dans l'article « De jolies URL dans vos applications Web JSF avec Pretty Faces ».

Compilez le projet d'exemple et importez-le dans Eclipse (comme expliqué dans le tutoriel « Importer un projet Maven dans Eclipse en 5 minutes ») ou dans l'IDE de votre choix.

Installez ensuite la webapp dans le serveur d'application de votre choix, par exemple Tomcat 6, ce que vous pouvez faire directement depuis Eclipse.

Pour suivre ce tutoriel, vous pouvez vous contenter de lire les codes proposés ci-dessous (codes complets en annexe) et de faire confiance aux captures d'écran.

II-B. Ce que fait déjà le projet d'exemple

Le projet d'exemple est une petite webapp permettant de calculer plusieurs fonctions mathématiques célèbres. Cette application Web n'a rien de très complexe. Elle utilise le framework Web JSF, inclus dans Java JEE. Les fonctionnalités (calcul de la suite de Fibonacci et du factoriel) servent uniquement d'illustration.

La webapp est accessible à l'aide d'une adresse ressemblant à la suivante : http://localhost:8080/fibo-webapp-fluentlenium/

Image non disponible
Page d'accueil

À partir du menu, on peut aller sur la page qui nous intéresse, permettant de calculer la suite de Fibonacci par exemple. C'est à cette fonction que nous allons plus particulièrement nous intéresser dans la suite. Par défaut, lorsqu'aucun rang n'a été précisé dans l'URL, la page affiche le résultat au rang « 2 », correspondant aux valeurs de base.

Image non disponible
Rang 2

Il est bien entendu possible de calculer la suite de Fibonacci pour un autre rang, qu'on choisira à l'aide d'un champ de saisie.

Image non disponible
Rang 8

Dans la suite, on va donc tester que ce parcours fonctionne bien.

III. Action

III-A. Maven

Durée estimée : 1 minute.

Pour utiliser FluentLenium, il faut ajouter une dépendance dans le fichier « pom.xml » . Ici on va utiliser la version FestAssert, car elle est pratique, mais on peut se contenter de JUnit.

Dépendance dans le pom.xml
Sélectionnez

<dependency>
    <groupId>org.fluentlenium</groupId>
    <artifactId>fluentlenium-festassert</artifactId>
    <version>0.9.1</version>
</dependency>

Il n'est pas obligatoire de coder les tests dans le même projet que la webapp. La plupart du temps, vous allez d'ailleurs tester des webapp dont vous n'aurez pas le code. Elles seront peut-être même écrites à l'aide d'une autre techno comme PHP, .net ou tout simplement en HTML classique.

Puis relancer une installation Maven.

Commande Maven
Sélectionnez

mvn clean install eclipse:eclipse

En fonction des éléments déjà présents sur le disque dur, le résultat de l'installation Maven devrait ressembler à la trace suivante.

Commande Maven
Sélectionnez

C:\dvp\fibo-webapp-fluentlenium>set JAVA_HOME=C:\dev\javas\jdk1.6.0_24
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building fibo-webapp-fluentlenium 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: http://repo1.maven.org/maven2/org/fluentlenium/fluentlenium-core/0.9.1/fluentlenium-core-0.9.1.pom
Downloaded: http://repo1.maven.org/maven2/org/fluentlenium/fluentlenium-core/0.9.1/fluentlenium-core-0.9.1.pom (4 KB at 7.8 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/fluentlenium/fluentlenium-parent/0.9.1/fluentlenium-parent-0.9.1.pom
Downloaded: http://repo1.maven.org/maven2/org/fluentlenium/fluentlenium-parent/0.9.1/fluentlenium-parent-0.9.1.pom (9 KB at 63.2 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/seleniumhq/selenium/selenium-java/2.35.0/selenium-java-2.35.0.pom
Downloaded: http://repo1.maven.org/maven2/org/seleniumhq/selenium/selenium-java/2.35.0/selenium-java-2.35.0.pom (7 KB at 43.4 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/seleniumhq/selenium/selenium-parent/2.35.0/selenium-parent-2.35.0.pom
Downloaded: http://repo1.maven.org/maven2/org/seleniumhq/selenium/selenium-parent/2.35.0/selenium-parent-2.35.0.pom (10 KB at 58.8 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/seleniumhq/selenium/selenium-android-driver/2.35.0/selenium-android-driver-2.35.0.pom
...
[INFO] Not writing settings - defaults suffice
[INFO] File C:\dvp\fibo-webapp-fluentlenium\.project already exists.
       Additional settings will be preserved, run mvn eclipse:clean if you want old settings to be removed.
[INFO] Wrote Eclipse project for "fibo-webapp-fluentlenium" to C:\dvp\fibo-webapp-fluentlenium.
[INFO]
       Javadoc for some artifacts is not available.
       List of artifacts without a javadoc archive:
         o org.apache.httpcomponents:httpclient:4.2.1
         o org.apache.httpcomponents:httpcore:4.2.1
         o org.apache.httpcomponents:httpmime:4.2.3
         o io.netty:netty:3.5.2.Final

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:55.578s
[INFO] Finished at: Sat Nov 30 16:33:54 CET 2013
[INFO] Final Memory: 13M/118M
[INFO] ------------------------------------------------------------------------

On doit ensuite faire un refresh (touche F5) dans Eclipse pour faire apparaitre FluentLenium dans la liste des bibliothèques référencées.

III-B. Page Object Pattern

Durée estimée : 1 minute.

On va donc s'intéresser à trois écrans : la page d'accueil, la page pour calculer la suite de Fibonacci et la page des résultats. Avant de savoir si ces pages fonctionnent, encore faut-il savoir naviguer dessus.

FluentLenium recommande d'employer le pattern « Page Object Pattern » au lieu de coder les appels en dur.

On va donc créer trois classes dédiées à cette opération : HomePage, FiboPage et FiboResultPage. Il faut redéfinir les méthodes « getUrl() » et « isAt() ». Elles servent respectivement à indiquer l'adresse cible et savoir si on est bien arrivé. Voici ce que ça donne pour la première :

HomePage
Sélectionnez

public class HomePage extends FluentPage {

    private final static String URL = "http://localhost:8080/fibo-webapp-fluentlenium";
    private final static String TITLE = "fibowebapp";

    @Override
    public String getUrl() {
        return URL;
    }

    @Override
    public void isAt() {
        Assertions.assertThat(title()).isEqualTo(TITLE);
    }

}

Le titre des pages reste le même sur tout le site. Du coup, le test de la valeur du titre permet de savoir qu'on est sur le bon site, mais pas forcément sur la page d'accueil. Ici, ce n'est pas bien grave puisqu'on est surtout intéressé de savoir qu'on est bien sur le site, lorsqu'on parle de l'accueil, avec les menus et les éléments englobants. Si on veut vraiment la page d'accueil (et aucune autre), on devra être plus spécifique et on utilisera une des techniques qu'on va voir dans la suite.

Nous reviendrons rapidement sur les deux autres pages.

III-C. Un premier test

Durée estimée : 1 minute.

On peut maintenant tester si les pages fonctionnent bien. Voyons déjà ce que ça donne avec l'accueil. Pour cela, on va écrire un petit test :

Test de la page d'accueil
Sélectionnez

public class HomeTest extends FluentTest {

    public WebDriver webDriver = new HtmlUnitDriver();

    @Page
    public HomePage homePage;

    @Test
    public void testHomePage() {
        // Aller sur la page d'accueil
        goTo(homePage);

        // Verifier qu'on est bien arrive
        homePage.isAt();
    }

    @Override
    public WebDriver getDefaultDriver() {
        return webDriver;
    }
}

Avant de lancer le test, il faut évidemment démarrer le serveur.

III-D. Test de navigation

Durée estimée : 2 minutes.

Un test de navigation teste qu'on peut naviguer dans le site. Ici, on va simplement cliquer sur le menu « Fibonacci » et vérifier qu'on arrive sur la bonne page. Pour cela, on va partir de la page d'accueil.

Test de la page Fibonacci
Sélectionnez

public class FiboTest extends FluentTest {

    public WebDriver webDriver = new HtmlUnitDriver();

    @Page
    public HomePage homePage;

    @Page
    public FiboPage fiboPage;

    @Test
    public void testFiboPage() {
        // Aller sur la page d'accueil
        goTo(homePage);
        homePage.isAt();

        // Cliquer sur le menu
        clicFiboMenu();

        // Verifier qu'on est sur la page Fibonacci
        fiboPage.isAt();
    }

    private void clicFiboMenu() {
        // TODO
    }

    @Override
    public WebDriver getDefaultDriver() {
        return webDriver;
    }
}

Il reste à savoir ce qu'on va mettre dans la méthode « clicFiboMenu() ». Le dire en français est simple : on veut cliquer sur le lien « Fibonacci ». Le faire est un peu plus complexe, d'autant qu'il y a plusieurs manières d'y parvenir.

On peut rechercher le texte dans la page et cliquer dessus. Personnellement je ne suis pas fan de cette pratique, car elle nécessite beaucoup de travail dans un environnement multilingue. On peut aussi chercher le lien en parcourant la structure des balises de la page. Mais la moindre évolution dans la page rendra tous les tests obsolètes. On peut encore trouver le lien grâce à son id ou à un attribut de style. C'est ce que nous allons faire.

On va donc ajouter des identifiants à nos liens de menu, comme ça devrait être le cas dans tous les sites Web dignes de ce nom :

Ajout d'un id dans menu.xhtml
Sélectionnez

<pretty:link mappingId="fibonacci" id="fibo"> 
    Fibonacci
</pretty:link>

Au niveau du HTML généré, cela va se traduire par :

Le HTML du menu
Sélectionnez

<a id="fibo" href="/fibo-webapp-fluentlenium/fibo">Fibonacci</a>

On peut désormais utiliser cet id dans le test :

Dans le test
Sélectionnez

private void clicFiboMenu() {
    $("#fibo").click();
}

En voyant « $("#fibo") » dans ce bout de code, vous vous dites sûrement que ça ressemble à du jQuery et vous auriez bien raison. Mais n'allez pas vous imaginer que c'en est. Ça y ressemble (volontairement), mais c'est bien du Java. En effet, n'oubliez pas que le dollar est autorisé dans un nom de méthode, même si c'est très rarement utilisé. Vous trouverez la méthode « $(..) » dans la classe « Fluent ». Pour le coup, ici, c'est bien pratique, surtout si on fait le rapprochement avec jQuery qu'on utilise, côté navigateur (i.e. côté client), pour rechercher des éléments dans le DOM.

Il reste encore à écrire la méthode « isAt() » de « FiboPage ». Contrairement à la page d'accueil, on ne va pas se contenter de la valeur du titre.

Dans le code, on a ça :

Code HTML
Sélectionnez

<div id="content">
    <h1>Fibonacci</h1>
    <form id="j_idt22" enctype="application/x-www-form-urlencoded" 
        action="/fibo-webapp-fluentlenium/fibo?r=2" method="post" name="j_idt22">
</div>

Du coup, on peut prendre l'élément « h1 », représentant le titre de la section (supposé unique) dans la « div » avec l'id « content » :

FiboPage
Sélectionnez

public class FiboPage extends FluentPage {

    @Override
    public void isAt() {
        Assertions.assertThat( find("#content h1").first().getText() )
            .isEqualTo("Fibonacci");
    }
}

Pour comprendre ce bout de code, il faut savoir que la méthode « find() » renvoie une liste.

III-E. Test du formulaire

Durée estimée : 2 minutes.

Pour tester le formulaire, c'est à peine plus difficile. On va d'abord naviguer vers la bonne page, puis choisir un rang, puis vérifier qu'on arrive sur la page des résultats et enfin tester les valeurs fournies.

On peut se dire qu'on est sur la bonne page, si on voit le tableau des résultats. Pour l'identifier facilement, on peut de nouveau ajouter un id dans le code HTML :

Ajout d'un id
Sélectionnez

<p id="resultats">
    <table border="1">
        <thead>
            <tr>
                <th>Rang</th>
                <th>Valeur</th>

La suite est relativement la même que pour les pages précédentes :

FiboResultPage
Sélectionnez

public class FiboResultPage extends FluentPage {

    @Override
    public void isAt() {
        Assertions.assertThat(find("#resultats table").size()).isGreaterThan(0);
    }
}

Dans la suite, on va rester dans la même classe de test : pas la peine de multiplier inutilement les tests alors qu'on reste dans le même sujet… Par contre, on en profite pour factoriser un peu.

Résultats
Sélectionnez

public class FiboTest extends FluentTest {

    public WebDriver webDriver = new HtmlUnitDriver();

    @Page
    public HomePage homePage;

    @Page
    public FiboPage fiboPage;

    @Page
    FiboResultPage fiboResultPage;

    @Test
    public void testFiboPage() {
        goToFibo();
    }

    @Test
    public void testFiboCalcul() {
        // Arrange
        final String value = "8";
        final String expected = "21";

        // Act
        goToFibo();

        selectValue(value);
        clicCalculerBouton();

        fiboResultPage.isAt();

        // Assert
        Assertions.assertThat(findFirst("#res_" + value).getText()).isEqualTo(expected);

    }

    private void goToFibo() {
        goTo(homePage);

        homePage.isAt();

        clicFiboMenu();

        fiboPage.isAt();
    }

    private void selectValue(final String value) {

    }

    private void clicCalculerBouton() {

    }

    ...
}

Il ne reste plus qu'à coder la sélection d'une valeur et le clic sur le bouton. Pour ce dernier, c'est aussi simple que pour le clic sur le menu.

Clic sur le bouton
Sélectionnez

private void clicCalculerBouton() {
    fiboPage.submit();
}

Comme l'action de validation du formulaire est propre à la page, on va plutôt la coder dans « FiboPage » :

Soumission dans la page
Sélectionnez

public void submit() {
    submit("#fiboform");
}

Pour pouvoir faire ça de cette manière, il suffit de donner l'id « fiboform » au formulaire. Le code HTML n'en sera que plus propre. La bibliothèque va aller chercher toute seule les boutons du formulaire.

Pour choisir une valeur, ce n'est pas beaucoup plus difficile.

 
Sélectionnez

private void selectValue(final String value) {
    fillSelect("select", FilterConstructor.withId().endsWith("fiboselect")).withValue(value);
}

Vous vous demandez certainement pourquoi on n'indique pas simplement « #fiboselect » comme id. Cela vient du fait que JSF en a changé la valeur en la préfixant par quelque chose qu'on ne peut pas déterminer à l'avance…

On peut maintenant lancer le test qui devrait passer au vert, pour indiquer que tout est bon.

Comme me l'a fait très justement remarquer Nemek, un collègue de Developpez.com, s'il y a un préfixe, c'est qu'il y a un formulaire. Le préfixe est l'id du formulaire. Il suffit donc de donner un id au formulaire :

Un titre pour le formulaire
Sélectionnez

<h:form id="fiboform">
    ...

Du coup, on peut trouver la balise « SELECT » à l'aide de l'id généré « fiboform:fiboselect » et donc simplifier le test en conséquence :

Un peu plus simple...
Sélectionnez

private void selectValue(final String value) {
    //fillSelect("select", FilterConstructor.withId().endsWith("fiboselect")).withValue(value);
     fillSelect("#fiboform\\:fiboselect").withValue(value);
}

III-F. Des tests et des services

Durée estimée : 2 minutes.

On a déjà bien utilisé le POP (Page Object Pattern), mais nous ne sommes pas allé au bout du concept. En effet, on peut séparer la partie test, qui reprend du fonctionnel, de la partie page, qui gère ce qui est technique comme les sélecteurs CSS (les id pour nous).

Pour faire simple, tout ce qui contient un id (hors test de résultat, quoique  ?… cf. code complet en annexe) doit se trouver dans un objet Page. Et les tests utiliseront alors les nouveaux services proposés par les pages.

Pour la page d'accueil, tout est déjà bon. Pour son menu, on peut déporter le clic sur un menu particulier dans l'objet Page.

HomePage
Sélectionnez

public class HomePage extends FluentPage {
    ...

    public void clickOnFibonacciMenu() {
        $("#fibo").click();
    }
goToFibo
Sélectionnez

public class FiboTest extends FluentTest {
    ...

    private void goToFibo() {
        goTo(homePage);

        homePage.isAt();

        //clicFiboMenu();
        homePage.clickOnFibonacciMenu();

        fiboPage.isAt();
    }

On pourrait même avoir un POP spécifique pour le menu, qu'on inclurait dans les autres pages, comme une sous-page.

On fait de même pour la sélection d'un rang dans la liste et le clic sur le bouton de calcul :

FiboPage
Sélectionnez

public class FiboPage extends FluentPage {
    ...

    public void selectValue(final String value) {
        fillSelect("#fiboform\\:fiboselect").withValue(value);
    }
Test
Sélectionnez

public class FiboTest extends FluentTest {
    ...

    @Test
    public void testFiboCalcul() {
        // Arrange
        final String value = "8";
        final String expected = "21";

        // Act
        goToFibo();

        //selectValue(value);
        fiboPage.selectValue(value);

        //clicCalculerBouton();
        fiboPage.submit();

        fiboResultPage.isAt();

        // Assert
        Assertions.assertThat(findFirst("#res_" + value).getText()).isEqualTo(expected);

    }

Le code complet est proposé en annexe…

IV. Conclusion

Le contrat n'est pas tout à fait rempli puisqu'il aura fallu un peu plus de cinq minutes pour venir à bout de ce petit tutoriel. Toutefois on n'en est pas loin.

Les exemples utilisés peuvent sembler simples, voire trop simples, mais ils devraient être représentatifs des pages auxquelles vous allez (probablement) vous attaquer en premier. En quelques cas, on couvre donc une bonne partie des problématiques. Toutefois, on pourra aller bien plus loin avec FluentLenium (ainsi qu'avec Selenium), comme écrire des tests d'acceptance en mode BDD (Behavior Driven Developpement) par exemple. Ce sera le sujet d'un prochain article, car FluentLenium existe aussi en version utilisant Cucumber.

Notez tout de même qu'on a pris le problème un peu à l'envers puisqu'on écrit les tests après coup. On a donc été obligé d'adapter des pages déjà existantes. Dans une démarche TDD (Test Driven Development), BDD (Behavior Driven Development) ou encore 3T (Tests en Trois Temps), on aurait dû écrire les tests avant le code des pages. On aurait donc décidé à l'avance des points importants à repérer dans les pages. Et on les aurait écrites comme il faut, durant le développement, et non juste modifiées pour les faire coller à un besoin a posteriori

Vos retours nous aident à améliorer nos publications. N'hésitez donc pas à commenter cet article sur le forum : 1 commentaire Donner une note à l'article (5)

V. Remerciements

D'abord j'adresse mes remerciements aux créateurs de FluentLenium, qui simplifient mon quotidien, pour avoir développé une bibliothèque aussi utile et pour la maintenir. Je n'oublie pas tous les contributeurs qui rendent le projet encore meilleur.

Plus spécifiquement en ce qui concerne cet article, je tiens à remercier Mathilde Lemée et les membres de Developpez.com qui m'ont aidé à écrire cet article : Nemek, Mickael Baron et Claude Leloup.

VI. Annexes

VI-A. Liens

VI-B. Liens perso

Retrouvez ma page et mes autres articles sur Developpez.com à l'adresse
http://thierry-leriche-dessirier.developpez.com/#page_articlesTutoriels

Suivez-moi sur Twitter : @thierryleriche (https://twitter.com/thierryleriche)@thierryleriche

Et mon site perso : www.icauda.comICAUDA

VI-C. Code complet

menu.xhtml
Sélectionnez

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:pretty="http://ocpsoft.com/prettyfaces">

    <div id="menus">
        <pretty:link mappingId="fibonacci" id="fibo"> 
            Fibonacci
        </pretty:link><br/>

        <pretty:link mappingId="fibonacci2" id="fibo10"> 
            <f:param value="10" />
            Fibonacci de 10
        </pretty:link><br/>

        <pretty:link mappingId="fibonacci2" id="fiboDef"> 
            <f:param value="#{fiboBean.defaultRang}" />
            Fibonacci au rang DEFAULT_RANG
        </pretty:link><br/>

        <pretty:link mappingId="factoriel" id="fact"> 
            Factoriel
        </pretty:link><br/>
    </div>
</ui:composition>
fibonacci.xhtml
Sélectionnez

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    template="/template.xhtml">

    <ui:define name="mainContent">
        <div id="content">
            <h1>Fibonacci</h1>

            <h:form id="fiboform">
                <table>
                    <tr>
                        <td>Rang :</td>
                        <td>
                            <h:selectOneMenu id="fiboselect" value="#{fiboBean.rang}">
                                <c:forEach var="entry" begin="1" end="90">
                                    <f:selectItem itemLabel="#{entry}" itemValue="#{entry}" />
                                </c:forEach>

                            </h:selectOneMenu >
                        </td>
                        <td>
                            <h:commandButton id="fibobutton" value="Calculer" action="#{fiboBean.calculer}" />
                        </td>
                    </tr>
                </table>

                <c:if test="#{fiboBean.valeur ne null}">
                    <p>La valeur de la suite de Fibonacci pour le rang <b>#{fiboBean.rang}</b> est <b>#{fiboBean.valeur}</b>.</p>
                </c:if>

                <c:if test="#{fiboBean.valeurs ne null}">
                    <p id="resultats">
                        <table border="1">
                            <thead>
                                <tr>
                                    <th>Rang</th>
                                    <th>Valeur</th>
                                    <th>Valeur approximative</th>
                                    <th>Approximation</th>
                                </tr>
                            </thead>

                            <tbody>
                                <c:forEach var="item" items="#{fiboBean.valeursInversees}">
                                    <tr>
                                        <td>#{item.rang}</td>
                                        <td id="res_#{item.rang}">#{item.valeurExacte}</td>
                                        <td>#{item.valeurApproximative}</td>
                                        <td>#{item.approximation}</td>
                                    </tr>
                                </c:forEach>
                            </tbody>
                        </table>
                    </p>
                </c:if>
            </h:form>
        </div>
    </ui:define>

</ui:composition>
HomePage.java
Sélectionnez

package com.dvp.fibowebapp.page;

import org.fest.assertions.Assertions;
import org.fluentlenium.core.FluentPage;

public class HomePage extends FluentPage {

    private final static String URL = "http://localhost:8080/fibo-webapp-fluentlenium";
    private final static String TITLE = "fibowebapp";

    @Override
    public String getUrl() {
        return URL;
    }

    @Override
    public void isAt() {
        Assertions.assertThat(title()).isEqualTo(TITLE);
    }

    public void clickOnFibonacciMenu() {
        $("#fibo").click();
    }
}
FiboPage.java
Sélectionnez

package com.dvp.fibowebapp.page;

import org.fest.assertions.Assertions;
import org.fluentlenium.core.FluentPage;

public class FiboPage extends FluentPage {

    @Override
    public void isAt() {
        Assertions.assertThat(find("#content h1").first().getText()).isEqualTo("Fibonacci");
    }

    public void submit() {
        submit("#fiboform");
    }

    public void selectValue(final String value) {
        fillSelect("#fiboform\\:fiboselect").withValue(value);
    }

}
FiboResultPage.java
Sélectionnez

package com.dvp.fibowebapp.page;

import org.fest.assertions.Assertions;
import org.fluentlenium.core.FluentPage;

public class FiboResultPage extends FluentPage {

    @Override
    public void isAt() {
        Assertions.assertThat(find("#resultats table").size()).isGreaterThan(0);
    }

    public String getResultat(final String indice) {
        return findFirst("#res_" + indice).getText();
    }
}
HomeTest.java
Sélectionnez

package com.dvp.fibowebapp;

import org.fluentlenium.adapter.FluentTest;
import org.fluentlenium.core.annotation.Page;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

import com.dvp.fibowebapp.page.HomePage;

public class HomeTest extends FluentTest {

    public WebDriver webDriver = new HtmlUnitDriver();

    @Page
    public HomePage homePage;

    @Test
    public void testHomePage() {
        goTo(homePage);

        homePage.isAt();
    }

    @Override
    public WebDriver getDefaultDriver() {
        return webDriver;
    }
}
FiboTest.java
Sélectionnez

package com.dvp.fibowebapp;

import org.fest.assertions.Assertions;
import org.fluentlenium.adapter.FluentTest;
import org.fluentlenium.core.annotation.Page;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

import com.dvp.fibowebapp.page.FiboPage;
import com.dvp.fibowebapp.page.FiboResultPage;
import com.dvp.fibowebapp.page.HomePage;

public class FiboTest extends FluentTest {

    public WebDriver webDriver = new HtmlUnitDriver();

    @Page
    public HomePage homePage;

    @Page
    public FiboPage fiboPage;

    @Page
    FiboResultPage fiboResultPage;

    @Test
    public void testFiboPage() {
        goToFibo();
    }

    @Test
    public void testFiboCalcul() {
        // Arrange
        final String rang = "8";
        final String expected = "21";

        // Act
        goToFibo();

        // selectValue(value);
        fiboPage.selectValue(rang);

        // clicCalculerBouton();
        fiboPage.submit();

        fiboResultPage.isAt();

        // Assert
        Assertions.assertThat(fiboResultPage.getResultat(rang)).isEqualTo(expected);
    }

    private void goToFibo() {
        goTo(homePage);

        homePage.isAt();

        // clicFiboMenu();
        homePage.clickOnFibonacciMenu();

        fiboPage.isAt();
    }

    // private void selectValue(final String value) {
    // fillSelect("select",
    // FilterConstructor.withId().endsWith("fiboselect")).withValue(value);
    // fillSelect("#fiboform\\:fiboselect").withValue(value);
    // }

    // private void clicCalculerBouton() {
    // fiboPage.submit();
    // }

    // private void clicFiboMenu() {
    // $("#fibo").click();
    // }

    @Override
    public WebDriver getDefaultDriver() {
        return webDriver;
    }
}

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2013 Thierry Leriche-Dessirier. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.