đ» TP â DĂ©velopper des tests automatisĂ©s (avancĂ©)
1. Introduction
Ce TP a pour objectif de vous apprendre Ă configurer et Ă utiliser le framework de test JUnit sur un projet de code assez rĂ©aliste. En revanche, l’objectif n’est pas d’apprendre Ă trouver de bons scĂ©narios de test, car cela sera principalement Ă©tudiĂ© en TD.
2. Projet Ă tester
On vous demande de tester une partie d’une petite bibliothĂšque logicielle destinĂ©e Ă gĂ©rer un systĂšme de rĂ©servation de voyages en train.
Le projet est disponible ici : https://gitlab.univ-nantes.fr/naomod/testing/testing-resources/train-reservation
|
Ce projet fait un usage important de toute la partie de la bibliothÚque standard Java dédiée à la gestion du temps, notamment via les classes Quelques conseils :
|
3. Travail à réaliser
|
Avant tout, quelques points importants :
|
3.1. Préparation
-
Lisez le
READMEdu projet pour bien comprendre Ă quoi sert cette cette bibliothĂšque logicielle et comment on est en censĂ© s’en servir au sein d’un projet de dĂ©veloppement. -
RĂ©cupĂ©rez le projet Ă tester Ă l’aide d’un
git clone. -
En vous aidant du cours, ajoutez JUnit 5 comme dépendance Maven du projet.
-
En vous aidant du cours, préparez le répertoire devant contenir vos tests.
3.2. Test de TrainReservationFactoryImpl
Ă ce stade, vous avez peut-ĂȘtre constatĂ© que le projet Ă tester n’est pas trivial et comporte de nombreuses classes et mĂ©thodes.
Pour y aller en douceur, nous allons commencer par tester la classe TrainReservationFactoryImpl, dont la spĂ©cification se trouve dans l’interface TrainReservationFactory.
La classe TrainReservationFactoryImpl est ce qu’on appelle une fabrique d’objets.
Elle contient des mĂ©thodes createXXX permettant de crĂ©er les instances de base requises lors d’un usage de la bibliothĂšque.
Plus prĂ©cisĂ©ment, cette bibliothĂšque a Ă©tĂ© conçue de maniĂšre Ă ce que toute construction d’objet par unâ
e utilisateurâ
ice doit ĂȘtre accomplie via une instance TrainReservationFactoryImpl.
TrainReservationFactoryImpl n’est pas capable de crĂ©er des instances de toutes les classes disponibles, car des certaines classes ne doivent ĂȘtre instanciĂ©es que par d’autres classes du projet (par exemple un Trip doit forcĂ©ment ĂȘtre créé par un TicketReservationSystem).
|
Avant toute chose, prĂ©parez une classe de test oĂč vous mettre les scripts de test pour la classe TrainReservationFactoryImpl.
Puis, pour chaque méthode listée ci-dessous de la classe TrainReservationFactoryImpl :
-
Lisez la spĂ©cification de la mĂ©thode (dans l’interface Java implĂ©mentĂ©e par la classe)
-
Quel est le domaine d’entrĂ©e de la mĂ©thode ?
-
Quel est le domaine de sortie de la méthode ?
-
Implémentez les scripts de test pour les scénarios de test demandés.
Méthodes à considérer :
-
Méthode
createCity(String name)-
Le nom est null,
-
Le nom est vide,
-
L’objet est construit avec succĂšs.
-
-
Méthode
createTrain(String name, int maxPassengers)-
Le nom est null,
-
Le nom est rempli d’espaces,
-
Le nombre de passagers max est négatif,
-
L’objet est construit avec succĂšs.
-
-
Méthode
createTicketReservationSystem(ZoneId timeZone)-
Le fuseau horaire est
null, -
L’objet est construit avec succĂšs.
-
3.3. Exécution de la suite de tests
Au fur et Ă mesure de l’Ă©criture de vos scripts de test, exĂ©cutez-les de deux maniĂšres diffĂ©rentes :
-
Via Maven en ligne de commande,
-
Via votre IDE directement (IntelliJ, Visual Studio Code, etc.)
Observez que les deux exĂ©cuteurs de tests vous fournissent bien les mĂȘmes rĂ©sultats, simplement affichĂ©s diffĂ©remment.
3.4. Test de TicketReservationSystemImpl : premiĂšre partie
Le cĆur mĂ©tier de la bibliothĂšque se trouve au sein de la classe TicketReservationSystemImpl.
Un objet de type TicketReservationSystem nous permet de dĂ©finir un systĂšme ferroviaire (villes, voyages, etc.), et nous permet d’agir sur ce systĂšme en dĂ©finissant des trajets, des retards, des rĂ©servations ou annulations de billets, etc.
| Cette classe permet de se confronter assez fortement avec les difficultĂ©s du test logiciel dans un logiciel orientĂ© objet. Soyez trĂšs vigilants quant aux domaines d’entrĂ©e et de sortie de chaque mĂ©thode, qui sont gĂ©nĂ©ralement plus complexe qu’ils en ont l’air. |
Avant toute chose, prĂ©parez une classe de test oĂč vous mettre les scripts de test pour la classe TicketReservationSystemImpl.
Puis, pour chaque méthode listée ci-dessous de la classe TicketReservationSystemImpl :
-
Lisez la spĂ©cification de la mĂ©thode (dans l’interface Java implĂ©mentĂ©e par la classe)
-
Quel est le domaine d’entrĂ©e de la mĂ©thode ?
-
Quel est le domaine de sortie de la méthode ?
-
Implémentez (et exécutez) les scripts de test pour les scénarios de test demandés.
Méthodes à considérer :
-
Méthode
getAllBookedTickets():-
La liste des tickets est bien initialement vide.
-
La liste des tickets contient bien les tickets ajoutés à un ou plusieurs voyages.
-
-
Méthode
getAllCancelledTickets()-
La liste des tickets annulés est bien initialement vide.
-
La liste des tickets contient bien les tickets annulĂ©s au sein d’un voyage.
-
-
Méthode
findPossibleExchanges(Ticket ticket)-
Si aucun voyage n’est disponible (Ă part celui du ticket), rend bien une liste vide.
-
Si un voyage existe et remplit les contraintes, alors rend bien une liste avec ce voyage.
-
-
Méthode
findAvailableTrips(City origin, LocalDate date)-
Si aucun voyage n’existe Ă cette date, alors rend bien une liste vide.
-
Si aucun voyage n’existe avec cette ville pour origine, alors rend bien une liste vide.
-
Si un voyage existe avec la bonne ville d’origine et la bonne date, alors rend une liste avec ce voyage.
-
| N’hĂ©sitez pas Ă vous rĂ©fĂ©rer au cours pour aller relire les diffĂ©rents types d'assertions offertes par JUnit 5 ! |
| Pour le moment on ne se pose pas la question de si ces scĂ©narios de tests sont de bonne qualitĂ©, ou bien s’il sont suffisants pour notre projet. Cela sera traitĂ© dans une autre partie du cours. |
3.5. RĂ©-organisation de la suite de tests
Pour vos premiers scénarios de tests, vous avez dû préparer différents lots de données de test (différents voyages, tickets, villes, etc.).
En vous aidant du cours, faites usage de l’annotation @BeforeEach afin de factoriser la prĂ©paration de vos donnĂ©es de test au sein d’une seule mĂ©thode de votre classe de test, et faites ensuite usage de ces donnĂ©es factorisĂ©es au sein de vos diffĂ©rentes scripts de test.
Puis, faites usage de @Nested pour créer une classe interne de test pour chaque méthode testée.
Si vous avez déjà fait bon usage de @BeforeEach et @Nested pour votre suite de tests initiale, ignorez cette question.
|
3.6. Test de TicketReservationSystemImpl : deuxiĂšme partie
Toujours pour TicketReservationSystemImpl, pour chaque méthode listée ci-dessous :
-
Quel est le domaine d’entrĂ©e de la mĂ©thode ?
-
Quel est le domaine de sortie de la méthode ?
-
Implémentez (et exécutez) les scénarios de test demandés.
Méthodes à considérer :
-
Méthode
cancelTrip(Trip trip)-
Un voyage qui n’Ă©tait pas dĂ©jĂ annulĂ© devient bien annulĂ© (Ă la fois du point de vue de l’objet
Tripet de l’objetTicketReservationSystem) -
Annuler un voyage déjà annulé ne fait rien.
-
-
Méthode
createTrip(City origin, City destination, Train train, Instant departure, Instant arrival):-
Si le nouveau trajet a lieu avant le dernier trajet du train, alors une exception
TripExceptionest renvoyée. -
Si l’origine et la destination sont identiques, une exception
TripExceptionest renvoyée. -
Si le dernier trajet enregistrĂ© pour le train a pour destination une ville diffĂ©rente de la ville d’origine du nouveau trajet, alors une exception
TripExceptionest renvoyée. -
Si toutes les contraintes sont respectées, alors (a) un objet
Tripest bien créé avec toutes les informations demandĂ©es, et (b) cet objet est bien ajoutĂ© Ă l’ensemble des voyages enregistrĂ©es dans leTicketReservationSystem
-
-
Méthode
delayTripDeparture(Trip trip, Duration delay)-
Ătant donnĂ© un voyage valide et un dĂ©lai non nul, un dĂ©lai est bien ajoutĂ© Ă la fois pour le dĂ©part et l’arrivĂ©e d’un train.
-
-
Méthode
delayTripArrival(Trip trip, Duration delay)-
Ătant donnĂ© un voyage valide bien enregistrĂ© dans le systĂšme, un dĂ©lai est bien ajoutĂ© pour l’arrivĂ©e du train.
-
Ătant donnĂ© deux voyages valides, bien enregistrĂ©s dans le systĂšme, avec le mĂȘme train, un dĂ©lai ajoutĂ© au 1er train est bien rĂ©percutĂ© sur le dĂ©part du 2e train pour l’arrivĂ©e du train.
-
| Ă nouveau, n’hĂ©sitez pas Ă vous rĂ©fĂ©rer au cours pour aller relire les diffĂ©rents types d’assertions offertes par JUnit 5, notamment en ce qui concerne les exceptions ! |
3.7. (Optionnel) Continuer
N’hĂ©sitez pas Ă vous entraĂźner en continuant d’enrichir la suite de tests comme bon vous semble ! Toutes les mĂ©thodes sont bien documentĂ©es, donc intuitivement vous pourrez trouver pas mal de choses Ă tester.
Mais notez qu’il faudra attendre le chapitre sur les approches de test pour aller au delĂ de l’intuition et apprendre Ă rigoureusement sĂ©lectionner les scĂ©narios de test nĂ©cessaires đ.