Vous êtes sur la page 1sur 7

LOG4500

Travail Pratique 1
Tests unitaires
John Mullins Pascal Bachand
20 septembre 2006

1 Introduction
1.1 Mise en situation
Vous personnifiez deux jeunes brillant(e)s entrepreneur(e)s ayant fondé une entreprise
sur le point de faire l’offre initiale d’action sur le marché. Vous avez jusqu’ici acquis une
bonne réputation en recyclant des travaux pratiques de Poly à des clients qui n’y ont vu
que du feu... Il vous reste un dernier contrat avant d’aller faire les gros bidoux sur le
plancher de la bourse. Quelqu’un, quelque part à la direction de l’UdM, subissant
probablement la pression des bonzes l’UNESCO (institut de la statistique), a pris la
décision de remplacer les ascenseurs du Pavillon Principal. Le contracteur responsable
des travaux a fait appel à votre organisation pour programmer le contrôleur de
l’ascenseur. Comme vous n’avez aucune expérience avec ce genre de système et que
votre réussite aura une incidence majeure sur la valeur (virtuelle) de votre entreprise,
vous décider de construire une simulation en Java afin de tester la conception de votre
contrôleur.

1.2 Objectifs généraux


Vous avez récupéré une spécification en langue naturelle d’un contrôleur d’ascenseur sur
la Toile et l’avez adapter à votre projet de simulateur (section4 4 Spécification). Vous
planifiez effectuer les tests en trois étapes :
– TP1 : Développement et tests unitaires pour tester le comportement local (section 4.1
Comportement local).
– TP2 : Instrumentation du code et couverture
– TP3 : Suite de tests fonctionnels et d’intégration pour tester le comportement global
(section 4.2 Comportement global).

De plus, afin d’épater le parterre, vous planifier de démontrer que vous n’avez aucune
crainte d’utiliser des méthodes plus systématiques et que, conséquemment, votre
organisation se démarque franchement des autres appelés du marché :
– TP4 : Vérification automatique avec SPIN
– TP5 : Méthode déductive
2 TP1 : Développement du simulateur et tests unitaires
Le simulateur est développé en Java. Un objet Simulateur se charge d’établir la
communication entre les différents objets (Porte, Usager, Ascenseur).

2.1 Simplifications
Vous décidez d’y aller avec une première itération du simulateur o`u les simplifications
suivantes s’appliquent :
– Un seul ascenseur
– Deux usagers au même étage doivent demander l’ascenseur pour la même direction.
Dans le cas contraire, un usager attend que l’autre utilise l’ascenseur.

2.2 Code et modélisation UML


Vous disposez d’un début d’implantation et d’une modélisation du système en UML
(Figure 1).

Figure 1. Modélisation UML


2.3 Exemple de trace
Si vous avez implanté correctement le comportement local décrit dans la spécification
(section 4.1 Comportement local), vous devriez obtenir un trace d’exécution similaire à la
suivante (avec le préambule établit initialement dans Simulateur) :

Début de la simulation
1. # Usager[0]: # effectue l'appel 2-UP
2. # Usager[1]: # effectue l'appel 3-DOWN
3. + Ascenseur: + direction: UP
4. + Ascenseur: + étage: 2
5. + Ascenseur: + arrêt a l'étage 2
6. * Porte étage 2: * ouverture
7. # Usager[0]: # entre dans l'ascenseur
8. # Usager[0]: # entre la destination 3
9. * Porte étage 2: * fermeture
10. + Ascenseur: + fin de l'arrêt
11. + Ascenseur: + direction: UP
12. + Ascenseur: + étage: 3
13. + Ascenseur: + arrêt a l'étage 3
14. * Porte étage 3: * ouverture
15. # Usager[0]: # destination atteinte
16. # Usager[1]: # entre dans l'ascenseur
17. # Usager[1]: # entre la destination 1
18. * Porte étage 3: * fermeture
19. + Ascenseur: + fin de l'arrêt
20. + Ascenseur: + direction: DOWN
21. + Ascenseur: + étage: 2
22. + Ascenseur: + direction: DOWN
23. + Ascenseur: + étage: 1
24. + Ascenseur: + arrêt a l'étage 1
25. * Porte étage 1: * ouverture
26. # Usager[1]: # destination atteinte
Fin de la simulation

2.4 Tests unitaires


Les tests unitaires visent à valider le comportement d’une composante d’un logiciel. En
programmation OO, une composante consiste généralement en une classe. Au cours de
ce TP vous aurez à tester les classes Porte, Ascenseur et Usager et pour ce faire, vous
devrez instrumenter le code de manière à ce que ces classes soit bel et bien testées de
manière indépendante. Pour cela vous aurez à prendre en considération les concepts de
Stubs et Drivers.

Dans notre design, c’est la classe Simulateur qui démarre les objets et gère les signaux
entre eux, c’est pourquoi la classe de TestSimulateur hérite de Simulateur et l’emploi en
tant que driver. Vous pouvez donc utiliser ses attributs et ses signaux pour gérer le flot
de vos tests.
Les autres classes qui ne sont pas testées agiront en tant que stubs et ne seront donc pas
actives; vous devez donc vous assurer que leur comportement n’est pas démarré par la
méthode « run() ». Vous pouvez par contre créer des instances de ces classes et modifier
leurs attributs de manière à modifier l’état du système…

3 Outils
Vous disposez des outils suivants.

3.1 Scripts d’exécution


Trois scripts sont fournis avec le code source : ./compile.sh qui permet de faire la
compilation du code .java en classes exécutables .class; ./run.sh qui permet d’exécuter le
simulateur; et ./test.sh qui permet d’exécuter vos tests unitaire JUnit.

3.2 eclipse
Éditeur graphique Java ainsi qu’un environnement de compilation et de tests. Nous vous
suggérons d’utiliser cet outil de programmation, mais vous pouvez aussi utilisez tout
autre éditeur ainsi que les scripts fournis si nécessaire. Si vous utilisez eclipse pour la
première fois, lisez le tutoriel :
http://www.info.polymtl.ca/~log4500/demarrer_eclipse.html qui vous guidera pour
l’ouverture d’un projet, ainsi que l’exécution du simulateur et de vos tests.

3.3 librairie JUnit


Cette librairie Java offre des classes et méthodes qui vous permettront de systématiser
vos tests unitaires et de les exécuter à la chaîne à partir de la ligne de commande (script
./test.sh) ou d’une interface graphique (via eclipse). http://www.junit.org/index.htm

3.4 argoUML
Éditeur de graphes UML open source. http://argouml.tigris.org/

3.5 Hansel
Cet outil vous permet de systématiser certains tests de couverture.
http://hansel.sourceforge.net/

3.6 SPIN
Cet outil permet une vérification automatique du comportement global d’une
modélisation du système. http://spinroot.com/spin/whatispin.html
4 Spécifications
4.1 Comportement local
4.1.1 Les portes
Variables
– étage : l’étage de la porte [de 1 à nb. d’étages]

Comportement
[1] Attendre que l’ascenseur soit à l’arrêt à l’étage de la porte
[2] Ouvrir la porte
[3] Attendre un certain laps de temps [3 sec.]
[4] Fermer la porte
[5] Signaler à l’ascenseur qu’il peut redémarrer

4.1.2 Les usagers


Variables
– étage : l’étage courant de l’usager
– direction : la direction que l’usager veut emprunter
– destination : la destination de l’usager

Comportement
[1] Tant que la porte est close ou la direction de l’ascenseur incorrecte :
[1.1] Si aucun appel n’est signalé, l’usager effectue un appel
[1.2] Attendre que la porte s’ouvre…
[1.3] Décider d’entrer ou non (l’usager peut être distrait)
[1.4] Si la porte est toujours ouverte, entrer dans l’ascenseur
[2] Signaler la destination
[3] Attendre que l’ascenseur soit à destination et que la porte s’ouvre
[4] Sortir et terminer

4.1.3 L’ascenseur
Variables
– étage : l’étage courant de l’ascenseur
– direction : la direction courante de l’ascenseur
– destinations : un vecteur des destinations entrées par les usagers
– appels : un vecteur des appels effectués par les usagers

Comportement
[1] Si l’ascenseur n’a aucune direction, mais qu’il existe un appel à l’étage, prendre la
direction de cet appel.
[2] Ouvrir la porte si nécessaire
[2.1] Signaler l’arrêt
[2.2] Attendre la fermeture de la porte
[2.3] Effacer l’appel ou la destination pour l’appel courant
[3] Choisir la direction :
[3.1] S’il existe une destination au dessus, changer la direction vers le haut
(respectivement, vers le bas, ou à l’étage (none))
[3.2] Sinon,
[3.2.1] Si la direction de l’ascenseur est vers le haut ou none :
3.2.1.1.S’il existe un appel au dessus, garder la direction vers le haut.
3.2.1.2.S’il existe un appel en dessous changer la direction vers le bas.
3.2.1.3.Sinon rester à l’étage (none).
[3.2.2] Si la direction de l’ascenseur est vers le bas :
3.2.2.1.S’il existe un appel en dessous, garder la direction vers le bas.
3.2.2.2.S’il existe un appel au dessus changer la direction vers le haut.
3.2.2.3.Sinon rester à l’étage (none).
[4] Monter ou descendre d’un étage selon la direction
[5] Renverser la direction si l’ascenseur atteint l’étage le plus haut (resp. le plus bas)

4.2 Comportement global


1. Lorsque l’ascenseur est en mouvement, aucune porte n’est ouverte.
2. Il est toujours vrai qu’un usager qui demande l’ascenseur y entrera fatalement
3. Il n’y a jamais plus d’une porte d’ouverte à la fois.
4. La distance parcourue par un usager est toujours égale à |source − destination|.

5 Travail à faire
5.1 À faire
1. Nous vous fournissons une implantation incomplète du Simulateur d’ascenseur.
Vous devez terminez sont implantation en respectant les spécifications fournis, et
plus particulièrement la méthode « choisir_direction() » de la classe
Ascenceur.java.
2. Utilisez la variable de DEBUG pour structurer vos sorties à l’écran durant votre
implémentation et déboguage. Implémentez aussi les méthodes « toString() »
pour les classes Ascenseur et Usager, que vous pourrez utilisez durant le
déboguage ainsi que vos tests unitaires.
3. Comme premier test d’intégration, vous devez reproduire la trace d’exécution
décrite à la section 2.3 Exemple de trace par la classe Simulateur en maintenant le
préambule tel qu’il est implanté dans la méthode « runSimulateur() ».
4. Dessiner les diagrammes de flot pour la méthode Usager ::run(), la méthode
Ascenseur ::choisirDirection(), et la méthode Ascenseur ::run().
5. Pour vous familiariser avec la librairie JUnit, vous devrez exécuter des tests
unitaires pour les 3 classes du comportement local. Nous vous fournissons le
travail pour la classe Porte; aidez-vous de cet exemple pour produire deux tests
unitaires de votre cru pour la classe Usager et la classe Ascenseur. La qualité ou
le pourcentage de couverture de vos tests ne seront pas évalué, mais la lisibilité du
code et clarté lors de l’exécution du test le sera, ainsi que votre
utilisation/compréhension de la librairie JUnit.
6. Identifier sur vos diagrammes de flots, la position des assertions de vos 4 tests
unitaires.
7. Répondre aux questions de discussion

5.2 À Remettre
Vous devez remettre une archive (tar –czvf nom_archive fichers_à_archiver) comprenant
les fichiers de votre implantation ainsi qu’un rapport comprenant :

5.2.1 Résultats
– Des extraits de code pertinents montrant que vous avez implanté correctement le
comportement local (méthode Ascenseur ::choisisrDirection()).
– Votre trace d’exécution du Simulateur
– Des extraits de codes montrant l’implantation de vos tests unitaires
– La trace d’exécution de vos tests unitaires
– Vos 3 diagrammes de flots avec l’emplacement des asserts de vos tests unitaires

5.2.2 Discussion
Nous demandons une très courte réponse à vos questions (1-3 lignes seulement)!
1. Pour vos 4 tests unitaires, faites une courte description de la motivation derrière
votre choix de test, et/ou du comportement que vous vouliez vérifier.
2. Quelle est la motivation de faire des tests unitaires?
3. Quelle est la motivation de structurer ses tests dans une classe telle que
TestSimulateur?
4. Quelles seraient les prochaines étapes?
5. Comment évaluer la qualité de vos tests?

Vous aimerez peut-être aussi