:: Enseignements :: Master :: M1 :: 2015-2016 :: Programmation Orientée Objet - Design Patterns ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | TDD |
Ce TD se déroule en autonomie. Les rendus sont à faire sur la plate-forme elearning.
Les consignes précises du rendu :
- UN seul zip pour l'nsemble des sources + photo UML + readme au format MarkDown + ...
- nommage du zip: NOM_PRENOM-td1.zip
Rappel : le travail en autonomie peut inclure des discussions entre
vous mais le résultat / le rendu doit être le résultat de VOTRE
compréhension.
Le but de ce TD est d'utiliser la méthodologie Test Driven Development (ou TDD)
pour résoudre un problème simple la conversion de nombre Romain sous forme
de chaîne de caractère en entier et vice-versa.
Comme son nom de suggère, le principe du TDD consiste à écrire
dans un premier temps les tests qui vont ensuite servir de base
pour valider l'implantation qui sera écrite dans un second temps.
Exercice 1 - Questions
Les réponses aux questions doivent être faites en 15
minutes maximum
(ensuite les rendus ne seront plus possibles)
Ne faites
pas de copier/coller Wikipedia ! ce qui nous intéresse, c'est
votre compréhension et vos mots !
- Quel est la différence entre tests unitaires et tests d'intégration ?
- D'après vous, dans quel cadre la méthodologie TDD est-elle adaptée ?
- Comment vérifier que vos tests unitaires JUnit sont suffisants par rapport au code du programme ?
Exercice 2 - Conversion de nombre Romain vers les entiers
Dans un premier temps, nous allons nous intéresser au cas simple,
où l'on cherche à convertir un chiffre romain unique passé sous
forme d'une chaîne de caractères en l'entier correspondant.
La table de correspondance des chiffres Romain est la suivante
chiffre entier chiffre entier
"I" -> 1 "L" -> 50
"V" -> 5 "C" -> 100
"X" -> 10
Voici un exemple de test unitaire utilisant JUnit 4.
package fr.umlv.designpattern.tdd;
import static org.junit.Assert.*;
import org.junit.Test;
public class RomanNumeralsTest {
@Test
public void testToInteger1() {
assertEquals(1, RomanNumerals.toInteger("I"));
// a completer
}
}
-
Créer le fichier de test RomanNumeralsTest
et demander à Eclipse (au lieu de le faire à la main)
de créer la classe RomanNumerals ainsi
que la méthode toInteger.
-
Compléter la méthode testToInteger1 pour
couvrir le test des autres chiffres (on parle de chiffre
pas de nombre !).
Vérifier que votre test ne marche pas :)
-
Vous pouvez maintenant écrire l'implantation
de la méthode RomanNumerals.toInteger.
Vérifier que le test est maintenant au vert.
-
On souhaite maintenant gérer les nombres Romain composés
de plusieurs lettres. On ne va pour l'instant se restreindre
aux nombrex qui se lisent de gauche à droite, comme "VI" pour 6
ou "CII" pour 102, en supposant que les lettres sont toujours écrites
dans l'ordre décroissant ('C' est avant 'I' dans "CII").
Ecrire la méthode de test testToInteger2 qui test
une dizaine de nombres romains à plusieurs chiffres
(essayer de tester des combinaisons différentes).
Vérifier que le nouveau test ne passe pas.
-
Modifier l'implantation de votre méthode RomanNumerals.toInteger
pour que les tests soient valides.
Exercice 3 - Conversion d'entiers vers les chiffres Romain
-
Ecrire le test testToRomanNumerals1 qui vérifie
si la méthode RomanNumerals.toRomanNumerals marche
bien si on passe en paramètre un nombre correspondant à
un chiffre Romain.
De même que pour l'exercice 1, faire en sorte qu'Eclipse
vous génére le squelette de la méthode RomanNumerals.toRomanNumerals.
Puis vérifier que le test testToRomanNumerals1 ne marche pas.
-
Ajouter le test testToRomanNumerals2 qui vérifie que la méthode
RomanNumerals.toRomanNumerals marche avec des nombres
(donc pouvant être composés de plusieurs chiffres).
Vérifier que le test testToRomanNumerals2 ne marche pas.
-
Implanter la méthode RomanNumerals.toRomanNumerals.
L'idée est de tester si le nombre est supérieur à 100 et
de mettre un 'C' dans un StringBuilder et de continuer
jusqu'à ce que le nombre soit inférieur à 100.
Et de faire la même chose avec 50, 10, 5 et 1.
Si vous ne voyez pas comment faire sans copier coller, faite avec,
nous verrons plus tard comment améliorer les choses.
Vérifier que les tests testToRomanNumerals1 et
testToRomanNumerals2 sont verts.
-
En fait, il manque un test dans le cas où les nombres passés
en paramètre sont négatifs ou nuls. Que devrait faire l'implantation
de RomanNumerals.toRomanNumerals ?
Ecrire le test correspondant (testToRomanNumerals3)
et vérifier que le test ne passe pas.
Il y a deux façons d'écrire ce test, soit on utilise la propriété
expected de l'annotation @Test soit on utilise
la méthode org.junit.Assert.fail() dans un try/catch.
-
Modifier l'implantation pour que le test passe.
Exercice 4 - Nombre Romain préfix
En fait il est possible de former des nombres romain en mettant
une lettre plus petite devant une lettre plus grande dans certains cas.
Par exemple, "IV" peut se lire "I" (1) avant "V" (5) et donc avoir
pour valeur '4'.
Il y a plusieurs règles possibles mais la plus utilisée est qu'il
est uniquement possible d'utiliser "I" devant "V" ou "X", et "X" devant "L" ou "C".
-
Ajouter les méthodes testToIntegerPrefix et testToRomanNumeralsPrefix
qui testent que les implantations reconnaissent bien ces combinaisons.
Puis vérifier que les tests ne marche pas.
-
Modifier les implantations de RomanNumerals.toInteger et
RomanNumerals.toRomanNumerals et vérifier que les tests sont OK.
La déclaration suivante devrait vous éviter les copier/coller dans toRomanNumerals
private static final int[] VALUES = { 100, 90, 50, 40, 10, 9, 5, 4, 1 };
private static final String[] DIGRAMS = { "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
et devrait vous permettre de simplifier toInteger avec l'idée qu'il est possible
à partir du tableau des di-grams de créer une seule expression régulière (avec autant de
groupes que de di-grams) qui va reconnaitre si une partie d'une chaine de caractère
est un di-grams.
© Université de Marne-la-Vallée