Tests unitaires
[TP 3/4] - Génie Logiciel L3
Dans ce TP, on se propose dâexpĂ©rimenter lâutilisation des tests unitaires en Java. Pour cela, on va rĂ©aliser une classe permettant de gĂ©rer des chiffres romains.
Rappel sur les chiffres romains
Dans la numérotation romaine, il y a sept symboles combinés de différentes maniÚres pour composer les nombres :
- I = 1
- V = 5
- X = 10
- L = 50
- C = 100
- D = 500
- M = 1000
La construction des nombres plus complexes suit les rĂšgles suivantes :
- Les symboles sont additifs : I vaut 1, II vaut 2, VI vaut 6 (5 + 1), etc
- Les symboles des multiples (I, X, C et M) peuvent ĂȘtre rĂ©pĂ©tĂ©s jusquâĂ trois fois. Ă partir de quatre, il faut soustraire du symbole suivant. Ainsi, 4 est reprĂ©sentĂ© par IV, 40 sâĂ©crit XL, etc.
- De mĂȘme, si 8 est VIII, 9 est IX.
- Les symboles des â5â ne peuvent jamais ĂȘtre rĂ©pĂ©tĂ©s.
- Les chiffres romains sâĂ©crivent du plus grand vers le plus petit et se lisent de gauche Ă droite. Lâordre compte : DC est 600, mais CD est 400.
Les propriĂ©tĂ©s suivantes devront ĂȘtre respectĂ©es :
- Il nâexiste quâune seule maniĂšre de reprĂ©senter un nombre en chiffres romains
- Réciproquement, un nombre romain valide représente un seul nombre décimal
- Seuls les nombres entiers compris entre 1 et 3999 inclus peuvent ĂȘtre reprĂ©sentĂ©s avec ce systĂšme
Module de conversion
Les algorithmes de conversion sont assez simples et sont donnés ci-dessous.
Conversion dâun chiffre arabe vers un chiffre romain :
DONNĂES : table des symboles (symbole, nombre) connus
ENTRĂES : nombre entier inclus dans l'intervalle [1;3999] n
RĂSULTAT : chiffre romain
DĂBUT :
rĂ©sultat â ""
POUR CHAQUE couple(symbole, nombre) de la table des symboles, FAIRE :
TANT QUE n â„ nombre, FAIRE :
rĂ©sultat â rĂ©sultat + symbole
n â n - nombre
RETOURNER : résultat
FINConversion dâun chiffre romain vers un chiffre arabe :
DONNĂES : table des symboles (symbole, nombre) connus
ENTRĂES : chiffre romain s
RĂSULTAT : nombre entier en dĂ©cimal
DĂBUT :
rĂ©sultat â 0;
index â 0;
POUR CHAQUE couple (symbole, nombre) de la table des symboles, FAIRE :
TANT QUE SousChaine(s, index, index + Longueur(symbole)) = symbole,
FAIRE :
rĂ©sultat â rĂ©sultat + nombre
index â index + Longueur(symbole)
RETOURNER : résultat
FIN
Pour débuter, clonez le projet de départ :
git clone https://framagit.org/uca/genie-logiciel-l3/helper-tp3.git
Pour simplifier la conversion, les combinaisons soustractives ont Ă©tĂ© ajoutĂ©es Ă la table des symboles. De plus, lâexpression rĂ©guliĂšre de validation des chiffres romains vous est donnĂ©e.
Tests unitaires et TDD
Principe des tests unitaires
Les tests unitaires ont pour but de tester les fonctions (ou mĂ©thodes) Ă un niveau Ă©lĂ©mentaire, avec une approche âboĂźte noireâ, câest-Ă -dire que lâon ne connaĂźt que la signature de la fonction Ă tester. On teste donc des unitĂ©s fonctionnelles indĂ©pendantes dâun programme plus global.
Il existe des frameworks de test unitaire pour la plupart des langages de programmation, souvent inspiré de SUnit, le framework pour Smalltalk.
Les mĂ©thodes de test ne testent quâun aspect particulier du cas,
correspondant à une spécification particuliÚre, et lÚvent une exception
si le rĂ©sultat nâest pas celui attendu. Cette verification se fait par
lâintermĂ©diaire de mĂ©thodes spĂ©cifiques (assertEquals,
assertRaises, etc.). LĂ aussi, il existe de nombreuses bibliothĂšques
dâassertion.
Mise en oeuvre
Nous allons suivre les principes du dĂ©veloppement guidĂ© par les tests, ou TDD (Test Driven Development). Cela signifie que nous allons Ă©crire les tests avant dâĂ©crire le code. Câest un principe mis en Ćuvre dans les mĂ©thodes agiles.
Les tests Ă effectuer sont (au moins) les suivants :
- Tests de réussite :
- Donner les bonnes valeurs décimales pour des valeurs romaines connues ;
- Donner les bonnes valeurs romaines pour des valeurs décimales connues ;
- Tests dâĂ©chec :
- Ăchouer pour les valeurs nĂ©gatives ;
- Ăchouer pour des valeurs hors de lâintervalle [1;3999] ;
- Ăchouer pour des valeurs avec trop de rĂ©pĂ©titions de symboles ;
- Ăchouer pour des valeurs avec des rĂ©pĂ©titions de paires ;
- Ăchouer pour des valeurs avec des antĂ©cĂ©dents incorrects ;
- Tests de validité :
- Pour tout entier n inclus dans lâintervalle [1;3999] :
fromRoman(toRoman(n))= n.
- Pour tout entier n inclus dans lâintervalle [1;3999] :
Travail
LâidĂ©e est donc dâĂ©crire les tests en premier, et dâimplĂ©menter les fonctionnalitĂ©s petit Ă petit jusquâĂ ce que tous les tests passent :
- ImplĂ©mentez la totalitĂ© des tests unitaires dâaprĂšs les spĂ©cifications fournies ;
- Implémentez les méthodes
toRoman()etfromRoman()jusquâĂ ce que tous les tests passent ; - ImplĂ©mentez et testez les mĂ©thodes dĂ©finies dans
java.lang.Number(toString(),toDouble(), etc.) ; - Faites en sorte quâun chiffre romain soit comparable avec
nâimporte quel autre nombre (voir lâinterface
Comparable).
Le modĂšle fournit pour ce TP utilise lâoutil Gradle. Le fichier de
configuration build.gradle définit les tùches et les dépendances du
projet.
Pour exécuter les tests, lancez la tùche test de gradle :
./gradlew test