TP autour de test et de l'utilisation du debugger dans Eclipse
1 Premier projet avec Eclipse
Le travail en java à l'aide de l'environnement Eclipse est centré autour de la notion de projet. Un projet désigne
l'ensemble de constituants d'une application : fichiers source, manière de les compiler, manière d'exécuter les
programmes associés. Eclipse utilise son propre espace pour stocker les fichier associés à un projet. Généralement, cet
espace se trouve dans le répertoire eclipse-workspace
situé dans le répertoire de login (ou dans Documents
sous
Windows).
Pour commencer à travailler sur un ensemble de fichiers source en java il faut commencer par créer un projet :
File->New Project->Java->Java Project
Nommez votre projet et validez. Ce projet apparaît alors dans la partie gauche de la fenêtre, il faut alors le compléter
avec les fichier de départ que nous utiliserons dans le TP. Pour premier TP, nous partirons des fichiers de l'archive
TP.zip. Pour cela, nous devons choisir l'une des trois possibilités suivantes :
File->Import->General->Archive File
permet d'importer le contenu d'une archive (zip typiquement) au projet. On prendra soin de placer les fichier importés dans le répertoiresrc
du projet (dédié aux fichiers source). Avec cette méthode, les fichiers sont copiés dans le sous répertoire approprié deeclipse-workspace
;- Aller dans les propriétés du projet, puis dans la rubrique
Java Build Path
etLink source
, puis choisissez un répertoire ainsi qu'un nom associé dans Eclipse. Avec cette méthode, les fichiers présents dans le répertoire choisi sont directement modifiés par Eclipse ; - Aller dans le répertoire
eclipse-workspace/MonProjet/src
et placer les fichiers ici. Avec cette méthode on obtient un résultat équivalent à la première méthode. A noter qu'il faudra parfois demander à Eclipse de rafraîchir son affichage avecFile->Refresh
pour voir les fichiers.
Les fichiers donnés du TP du jour sont maintenant présents dans le paquetage par défaut, visible dans le répertoire où nous avons choisi de placer nos fichiers. Vous pouvez alors double cliquer sur l'un des fichiers pour éditer sont contenu. Les gains immédiats obtenus avec Eclipse sont des facilités de lecture et d'écriture :
- possibilité de masquer ou rendre visible le corps des méthodes (à l'aide du petit + ou - présent à gauche de la signature ;
- complétion automatique en cours de saisie : un menu s'affiche pendant la saisie, il est alors possible de continuer la
saisie normalement sans autre incidence ou alors de selectionner une option proposée dans le menu pour que le texte
associé s'écrive. Il est possible de provoquer l'affichage de ce menu avec
Ctrl-Espace
; - Indication à la volée des erreurs de syntaxe, soulignées en rouge, un explication détaillée apparaît en laissant la souris sur l'erreur ou en appuyant sur F2 avec le curseur sur l'erreur.
2 Premiers pas avec le Debugger
Aujourd'hui, nous vous fournissons un fichier Liste.java
qui ne fonctionne pas, il est truffé de bugs. Le but est de
corriger ce fichier, non pas en lisant le code et en cherchant au hasard les erreurs, mais en utilisant deux outils :
les tests et le debugger. Commencez par lire le fichier TestListe.java
qui contient un programme de test pour nos
listes constitué de méthodes qui nous aiderons à vérifier la cohérence de nos résultat (tete
, queue
, taille
,
contient
, triee
), de fonctions permettant d'exécuter chacune des méthodes de Liste
, d'afficher le résultat et de
vérifier sa cohérence (partiellement), ainsi que d'un programme principal qui lance des séries de tests.
Pour exécuter ce programme il vous suffit de cliquer sur la flèche verte de l'interface d'Eclipse. Celui-ci devrait
éventuellement vous demander quelle est la classe principale de votre projet (TestListe
) avant de
l'exécuter. Alternativement, vous pouvez selectionner le fichier principal et selectionner Run->Run as->Java
Application
.
Le programme s'exécute alors et vous pouvez remarquer que les résultats sont incorrects. Il semble que les tests de
sfcohérence (instructions assert
) ne sont pas exécutés. En effet, assert est une instruction spéciale de java qui est,
en temps normal, ignorée et ne génère aucun surcoût. Pour l'activer il faut le demander à la machine virtuelle : allez
dans Run->Run configurations
sélectionnez TestListe
et dans l'onglet Arguments
ajoutez -ea
dans la partie VM
arguments
. Exécutez, vous pouvez alors constater que, dès que l'expression donnée à un assert
est fausse, l'exécution
est stoppée par une exception indiquant la position de l'erreur.
Nous allons commencer par lancer le debugger pour observer l'exécution incorrecte. La première méthode contenant une
assertion invalide est insereTete
. Placez un point d'arrêt au début de cette fonction en double cliquant dans la
colonne tout à gauche de la fenêtre d'édition (une petite pastille bleue apparaît alors à cet endroit). Lancez alors
l'exécution avec le debugger à l'aide du bouton en forme d'insecte : Eclipse vous propose de changer de perspective,
acceptez, vous pouvez alors constater que l'organisation des fenêtres change afin d'être plus adaptée à l'activité de
debuggage. Le programme s'exécute alors et s'arrête au point d'arrêt que vous avez placé. Un fenêtre affiche le contenu
des variables et la ligne en cours (pas encore exécutée) est surlignée.
Avancez de ligne en ligne jusqu'à l.insererTete(element)
à l'aide du bouton représentant une flèche sautant au dessus
d'un point (Step Over). Vous pouvez remarquer que le programme s'exécute ligne par ligne en mettant à jour l'affichage
et les variables. Une fois arrivés à l.insererTete(element)
, nous souhaitons maintenant poursuivre l'exécution pas à
pas à l'intérieur de cette méthode. Pour cela utilisez le bouton en forme de flèche qui pointe entre deux points (Step
Into), vous arrivez alors dans la méthode insererTete
de la classe Liste
.
Dans la fenêtre consacrée aux variables, vous pouvez étendre this
en cliquant sur le triangle. Vous pouvez alors voir
la valeur des attributs de l'objet courant. Continuez l'exécution ligne par ligne et observez la valeur de ces attributs
ainsi que de ceux de l'objet pointé par nouvelle
. Vous devriez alors constater que tete
est mis à jour avec une
mauvaise valeur. Corrigez le problème. Une fois le problème corrigé, vous pouvez changer de perspective (pour revenir à
la perspective java) à l'aide du groupe de boutons situé en haut à droite.
3 Nous étoffons nos techniques
Pour la suite de l'exécution, vous pouvez constater que l'exécution tombe sur une boucle infinie après suppression de la
tête avant même les tests de cohérence. Lancez l'exécution à l'aide du debugger et, durant la boucle infinie,
interrompez la à l'aide du bouton pause. Le debugger arrête le programme dans une partie qui ne vous concerne pas
forcément (typiquement à l'intérieur des méthodes d'affichage), sélectionnez alors dans la pile d'appels (fenêtre en
haut à gauche) la partie du code qui vous intéresse (Liste.afficher()
). Continuez un peu l'exécution ligne par ligne
en observant la variable courant
, vous pouvez constater que la boucle est bien infinie car courant.suiv
est égal à
courant
. Reprenez alors la méthode précédente à base de point d'arrêt pour exécuter pas à pas la méthode
supprimeTete
de Liste
, trouvez l'erreur et corrigez la.
Maintenant, si vous n'avez pas trop bien corrigé les précédents bugs, nous devrions avoir une nouvelle erreur qui ne se
voit pas à l'affichage : l'insertion en queue de 3 dans une liste vide donne la liste avec pour seul élément 3, mais
l'une des assertions échoue. Si vous mettez un point d'arrêt sur queue
, et vous suivez son exécution vous devriez en
trouver la raison et pouvoir corriger les deux méthodes incriminées. Cela souligne l'importance des tests qui peuvent
couvrir plus de choses que ne le fait un simple affichage.
Pour le bug suivant, il faut attendre plusieurs insertions en queue avant que le bug ne survienne. Plus précisément,
c'est à la troisième itération qu'une assertion est violée. Pour le trouver, nous pouvons mettre un point d'arrêt dans
la boucle qui appelle insère queue, laisser le programme s'arrêter, lui dire de continuer (bouton avec une barre et un
triangle accolés) deux fois et exécuter pas à pas à partir du troisième arrêt sur le point d'arrêt. Mieux, nous pouvons
rendre le point d'arrêt conditionnel : dans la perspective de debuggage, cliquez sur l'onglet Breakpoints
, sur votre
point d'arrêt, puis cochez conditionnal
et saisissez une condition (ici i==2
). Le programme s'arrête maintenant
directement à la bonne itération ! Continuez l'exécution pas à pas et trouvez le bug. Come variante, vous pouvez vous
arrêter dans insereQueue
à la ligne appelant l.insererQueue(element)
lorsque l'élément vaut la valeur insérée
au moment du bug (7).
4 Test insuffisant
Pour le prochain les tests ne suffisent pas. Le bug se trouve dans l'insertion en place mais n'est pas detecté et n'est pas visible sur l'affichage. La méthode de test employée ici ne couvre simplement pas suffisament de cas. Pour faire apparaître le bug, essayez d'insérer 3 entiers dans tous les ordres possibles. Par exemple, avec 1, 2, et 3, essayez d'insérer 1 puis 2 puis 3, videz la liste, essayez 1 puis 3 puis 2, videz la liste essayez 2 puis 1 puis 3, et ainsi de suite. Le bug devrait alors apparaître. Corrigez le.
5 Conclusion
Pour terminer, utilisez toutes les techniques vues jusqu'alors pour corriger le dernier bug dans la fonction supprime
.