Ellipse Tutorial

Comment tester vos pages web Ellipse via JUnit ?



ATTENTION : Tutorial en cours d'écriture ! N'hésitez pas à nous signaler toute erreur ou suggestion.

Accès rapide :
   Quelques rappels JUnit
   Mise en oeuvre d'un test d'une page web

Quelques rappels JUnit

JUnit est une librairie permettant de réaliser des batteries de tests sur du code Java. Comme son nom l'indique, il permet notamment de mettre en oeuvre des tests unitaires sur vos classes, mais il permet aussi de réaliser des tests fonctionnels d'intégration, voir des tests techniques d'intégration. La librairie JUnit est disponible à partir de l'adresse suivante : http://www.junit.org.

On peut dire qu'il existe deux grandes versions de JUnit : JUnit 3 (ou versions précédentes) et JUnit 4 (et versions ultérieures). La différence fondamentale entre ces deux versions est liée aux apports de Java SE 5.0. Effectivement, avant cette version de Java, JUnit était basé sur un modèle d'héritage (junit.framework.TestCase) et sur des conventions de codage (les noms des méthodes de test devaient être préfixés des quatre lettres test).

Depuis JUnit 4, ces règles ont été abandonnées et à la place, l'utilisation d'annotations Java est préconisée (et notamment, l'annotation org.junit.Test). Cela permet notamment de pouvoir choisir une classe mére (au niveau de l'héritage), contrairement à la première technique qui impose la classe junit.framework.TestCase.

Enfin, n'oubliez pas que JUnit est intégré aux principaux IDE(Integrated Development Environment) Java (NetBeans et Eclipse notamment). Dans le cadre d'Eclipse, il vous suffit de cliquer avec le bouton droit de la souris sur le fichier comportant la classe de test, voir sur un package contenant ce fichier et de demander "Run As / JUnit Test". La vue "JUnit" devrait vous afficher les résultats de votre campagne de test. A titre d'exemple voici une capture d'écran de l'IDE Eclipse montrant l'intégration de JUnit (pour information, les tests montrés dans cette capture correspondent à une partie des tests de non-régression du framework Ellipse : ces tests sont vérifiés avant chaque mise en ligne d'une nouvelle version du framework). Notez aussi que des erreurs ont volontairement été produites afin de vous montrer un cas d'échec d'exécution des tests.

 

Mise en oeuvre d'un test d'une page web

Pour la mise en oeuvre d'un jeu de test sur une page web Ellipse, nous allons encore une fois, nous appuyer sur l'application de démonstration du framework Ellipse. Ce projet Ellipse contient un répertoire contenant deux tests pour notre page web d'authentification (Login.wp). Ce répertoire de test est accessible à partir de "WEB-INF/tests".

A titre d'exemple, voici le code à tester : il s'agit de la classe "corelib.services.web.samples.virtualcaddy.webpages.Login" permettant d'accepter ou de rejetter la connexion d'un utilisateur. Notez que si la connexion est acceptée, nous sommes renvoyés vers la page "SelectArticle.wp" et la session est mise à jour. Dans le cas contraire, il n'y a pas de redirection et la session reste inchangée.

01 package corelib.services.web.samples.virtualcaddy.webpages;
02
03 import corelib.services.web.components.Button;
04 import corelib.services.web.components.OutputText;
05 import corelib.services.web.components.TextBox;
06 import corelib.services.web.components.events.ActionEvent;
07 import corelib.services.web.components.events.ActionListener;
08 import corelib.services.web.samples.virtualcaddy.business.User;
09 import corelib.services.web.samples.virtualcaddy.business.UserHome;
10 import corelib.services.web.webapplications.WebPage;
11 import corelib.services.web.webapplications.events.WebPageEvent;
12
13 public class Login extends WebPage {
14
15     private TextBox        txtLogin    = null;
16     private TextBox        txtPassword = null;
17     private Button        btnConnect    = null;
18     private OutputText    lblResult    = null;
19
20
21     public void page_load( WebPageEvent webPageEvent ) {
22         this.traceLogger.info( "Virtual Caddy", "page_load" );
23         this.btnConnect.addActionListener( new ActionListener() {
24             public void actionPerformed( ActionEvent event ) {
25                 btnConnect_actionPerformed( event );
26             }
27         });
28     }
29
30     public void btnConnect_actionPerformed( ActionEvent event ) {
31         String login = txtLogin.getValue();
32         String password = txtPassword.getValue();
33
34         User user = UserHome.findByConnectInformations( login, password ); 
35         if ( user != null ) {
36             this.session.setAttribute( "user", user );
37             this.redirect( "SelectArticle.wp" );
38         } else {
39             lblResult.setText( "Bad connection for user : " + login );
40             this.traceLogger.warning( "Virtual Caddy", "Bad connection" );
41             this.traceLogger.error( "Virtual Caddy", "Bad connection" );
42         }
43     }
44 }

Il nous faut maintenant écrire au moins deux classes de tests pour vérifier une soumission en succès de la page (avec un couple login/password correct) et une soumission en échec de la page (couple login/password non reconnu). Il est important de tester les cas d'échec : il faut vérifier que si une telle situation arrive, votre code va se comporter correctement. J'ai même envie de dire qu'il est plus important de tester tous les cas d'échec connus. Voici le code du premier test.

01 package corelib.services.web.samples.virtualcaddy.webpages; 
02 
03 import org.junit.Assert; 
04 import org.junit.Test; 
05 
06 import corelib.services.web.samples.virtualcaddy.business.User; 
07 import corelib.services.web.tests.WebPageLoaderForTesting; 
08 
09 public class LoginTestsSuccess extends WebPageLoaderForTesting<Login> { 
10  
11     public LoginTestsSuccess() throws Exception { 
12         super( "Login.wp", "POST" ); 
13         this.request.setParameter( "txtLogin", "Malone" ); 
14         this.request.setParameter( "txtPassword", "P@ssw0rd" ); 
15         this.request.setParameter( "btnConnect", "" ); 
16         this.start(); 
17     } 
18  
19     @Test public void testReturns() { 
20         Assert.assertEquals( response.getStatus(), 200 ); 
21         Assert.assertEquals( response.getRedirectionURL(), "SelectArticle.wp" ); 
22         User user = (User)this.request.getSession().getAttribute( "user" ); 
23         if ( user instanceof User == false ) Assert.fail(); 
24     } 
25  
26 }

Si nous pouvons faire de tels tests, c'est parce-que la plate-forme Java EE et le framework Ellipse attachent les composants Web et le serveur HTTP par le biais d'interfaces Java. Ainsi, au lieu de présenter un vrai serveur HTTP à notre classe de test, nous lui fournissons un ensemble d'implémentations de ces interfaces permettant de simuler le comportement d'un serveur HTTP. On parle, en français, de bouchons, et en anglais, de mock objects. Vous trouverez les implémentations de ces bouchons dans les classes suivantes : corelib.services.web.tests.MockedHttpRequest, corelib.services.web.tests.MockedHttpResponse, corelib.services.web.tests.MockedHttpSession, corelib.services.web.tests.MockedHttpServlet et corelib.services.web.tests.MockedServletContext.

En ligne 20, nous vérifions le status HTTP renvoyé. Seules deux valeurs peuvent être retournées : 200 si tous va bien ou 500 si une erreur de traitement interne à la page à été dectectée. En ligne 21, on vérifie si une redirection sur la page "SelectArticle.wp" a bien été demandée. Puis en ligne 22, on vérifie que la session a bien été modifiée comme attendue.

Note importante : il est tout aussi important que vos composants Web soient couplés à vos objets métiers par interface pour favoriser (dans la même mesure) les tests de vos pages Web. Il est clair que ce n'est pas ce qui est présenté dans cet exemple (qui avait pour vocation d'être le plus simpliste possible).

L'exemple de code ci-dessous montre un exemple de test de la page Web pour un couple login/password non autorisé. Son code est relativement similaire à l'exemple précédent.

01 package corelib.services.web.samples.virtualcaddy.webpages;
02
03 import org.junit.Assert;
04 import org.junit.Test;
05
06 import corelib.services.web.samples.virtualcaddy.business.User;
07 import corelib.services.web.tests.WebPageLoaderForTesting;
08
09 public class LoginTestsFailure extends WebPageLoaderForTesting<Login> {
10
11     public LoginTestsFailure() throws Exception {
12         super( "Login.wp", "POST" );
13         this.request.setParameter( "txtLogin", "Toto" );
14         this.request.setParameter( "txtPassword", "Titi" );
15         this.request.setParameter( "btnConnect", "" );
16         this.start();
17     }
18
19     @Test public void testReturns() {
20         Assert.assertEquals( response.getStatus(), 200 );
21         Assert.assertEquals( response.getRedirectionURL(), null );
22         User user = (User)this.request.getSession().getAttribute( "user" );
23         if ( user != null ) Assert.fail();
24     }
25
26 }

ATTENTION : Ellipse Framework vous est proposé en version beta (d'évaluation) afin de vous permettre d'évaluer ce framework. Infini Software se dégage de toutes responsabilités relatives à l'utilisation de ce framework. De plus, Infini Software ne pourra nullement être tenu responsable de l'utilisation des informations présentes dans ces tutoriaux.

Dominique LIARD - © 2007..2010 SARL Infini Software - Tous droits réservés
Les autres marques et les noms de produits cités dans ces documents sont la propriété de leurs détenteurs respectifs.