En ce début d’année, je vous adresse mes vœux. Savez-vous que 2016 sera bissextile ? Voici une bonne occasion pour écrire et tester un petit bout de code.
Si on s’en réfère à la page Wikipedia consacrée aux années bissextiles, voici les critères pour dire si une année est bissextile :
- Si l’année est divisible par 4 (RG01) mais non divisible par 100 (RG02)
- ou si l’année est divisible par 400 (RG03)
2016 est donc bien bissextile. En revanche, 2014 et 2015 n’en étaient pas. L’année 2000 était bien bissextile mais pas 1900.
Je vous propose qu’on programme cela en utilisant la méthode 3T (Tests en Trois Temps), inspirée des TDD.
On va commencer par écrire une méthode vide, avec juste ce qu’il faut comme doc :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class Calculette { /** * Indique si l'annee passee en parametre est bissextile. * * Une annee bissextile repond aux criteres suivants : * - annee est multiple de 4 (RG01) mais pas de 100 (RG02) * - SAUF si annee est multiple de 400 (RG03) * * REGLES : RG01, RG02, RG03 * * @param annee * @return true si l'annee est bissextile et false sinon. */ public boolean isBissextile(final int annee) { throw new UnsupportedOperationException("Bientot..."); } } |
On peut maintenant écrire le code de test, ce qui correspond au second temps de 3T, en utilisant les exemples mentionnés plus haut.
Dans mes autres billets consacrés aux tests, je vous disais que, faute de mieux, on pouvait écrire les tests dans l’ordre où ils arrivent. Ici, je pense qu’il faut les écrire dans l’ordre où ils sont énoncés car cela correspond déjà à l’ordre logique. On va donc commencer par la règle RG01.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class CalculetteTest { private Calculette calc; @Before public void setUp() throws Exception { calc = new Calculette(); } /** * Test si l'annee est bissextile. * * REGLE : RG01 * * annee : 2016 * bissextile : oui */ @Test public void testMultipleDe4_RG01(){ // Arrange final int annee = 2016; final boolean expected = true; // Act final boolean bissextile = calc.isBissextile(annee); // Assert Assert.assertEquals(expected, bissextile); } } |
On fait de même avec tous les exemples et règles. Et on en profite pour factoriser :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | public class CalculetteTest { private Calculette calc; @Before public void setUp() throws Exception { calc = new Calculette(); } /** * Test si l'annee est bissextile. * * REGLE : RG01 * * annee : 2016 * bissextile : oui */ @Test public void testMultipleDe4_RG01() { // Arrange final int annee = 2016; final boolean expected = true; // Act et Assert testBissextile(annee, expected); } /** * Test si l'annee est bissextile. * * REGLE : RG02 * * annee : 1900 * bissextile : non */ @Test public void testMultipleDe100_RG02() { // Arrange final int annee = 1900; final boolean expected = false; // Act et Assert testBissextile(annee, expected); } /** * Test si l'annee est bissextile. * * REGLE : RG03 * * annee : 2000 * bissextile : oui */ @Test public void testMultipleDe400_RG03() { // Arrange final int annee = 2000; final boolean expected = true; // Act et Assert testBissextile(annee, expected); } /** * Test si l'annee est bissextile. * * REGLE : RG01 * * annee : 2014 * bissextile : non */ @Test public void testNonBissextile2014_RG01() { // Arrange final int annee = 2014; final boolean expected = false; // Act et Assert testBissextile(annee, expected); } /** * Test si l'annee est bissextile. * * REGLE : RG01 * * annee : 2015 * bissextile : non */ @Test public void testNonBissextile2015_RG01() { // Arrange final int annee = 2015; final boolean expected = false; // Act et Assert testBissextile(annee, expected); } private void testBissextile(final int annee, final boolean expected) { // Act final boolean bissextile = calc.isBissextile(annee); // Assert Assert.assertEquals(expected, bissextile); } } |
Notez que vous pouvez produire un code plus concis et plus lisible en écrivant des tests paramétrés.
À ce stade, tous les tests sont rouges, ce qui est parfaitement normale puisque nous n’avons encore rien programmé.
Dans la suite, on va justement programmer la méthode mais on ne va pas chercher à optimiser le code, en tous cas pour l’instant. Le plus simple est de prendre les tests dans l’ordre.
1 2 3 4 5 6 7 8 9 10 | public boolean isBissextile(final int annee) { // RG01 if (annee % 4 == 0) { return true; } throw new UnsupportedOperationException("Tres tres bientot..."); } |
Une partie des tests passent déjà au vert. On peut continuer tranquillement :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public boolean isBissextile(final int annee) { // RG02 if (annee % 100 == 0) { return false; } // RG01 if (annee % 4 == 0) { return true; } return false; } |
On est presqu’à la fin :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public boolean isBissextile(final int annee) { // RG03 if (annee % 400 == 0) { return true; } // RG02 if (annee % 100 == 0) { return false; } // RG01 if (annee % 4 == 0) { return true; } return false; } |
Et voilà le travail… Tout devrait passer au vert chez vous aussi.
Pour finir, et comme de coutume, je vous souhaite une bonne année, une bonne santé, de bons tests et de bons développements.