Une année bissextile

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.

Laisser un commentaire