24/02/2013

Styles de Test

Voici un article sur les différents style de test, qui reflète à peu près l'évolution de la manière dont j'ai personnellement écrit des test.

 

Le test basique:

   @Test
    public void testBuildFullName_tooBasic() {
        Person person = new Person();
        person.firstName = "Francois";
        person.lastName = "Wauquier";
        String fullName = person.buildFullName();
        assertEquals("Francois WAUQUIER", fullName);
    }


Les assertions avec Fest:

   @Test
    public void testBuildFullName_Fest() {
        Person person = new Person();
        person.firstName = "Francois";
        person.lastName = "Wauquier";
        String fullName = person.buildFullName();
        assertThat(fullName).isEqualTo("Francois WAUQUIER");
    }

 

Distinguer les 3 blocs (Initialisations, Action, Assertions):
    @Test
    public void testBuildFullName_BDD() {
        // Given
        Person person = new Person();
        person.firstName = "Francois";
        person.lastName = "Wauquier";
        // When
        String fullName = person.buildFullName();
        // Then
        assertThat(fullName).isEqualTo("Francois WAUQUIER");
    }


Utiliser des constructeurs pour les tests. Permet de consolider les objets métier en se posant la question des attributs obligatoires pour construire un objet, mais c'est un peu intrusif sur le code de production, si le constructeur n'est appellé que par les tests.
    @Test
    public void testBuildFullName_Constructor() {
        // Given
        Person person = new Person("Francois", "Wauquier");
        // When
        String fullName = person.buildFullName();
        // Then
        assertThat(fullName).isEqualTo("Francois WAUQUIER");
    }


Utiliser le pattern builder est à la fois plus facile à lire, à maintenir, et moins intrusif. Il est possible de générer automatiquement les classes builder.
    @Test
    public void testBuildFullName_Builder() {
        // Given
        Person person = new PersonBuilder().withFirstName("Francois").withLastName("Wauquier").buildPerson();
        // When
        String fullName = person.buildFullName();
        // Then
        assertThat(fullName).isEqualTo("Francois WAUQUIER");
    }


Ecrire le test en une seule ligne. On est content d'avoir réussi à l'écrire, mais je me suis aperçu qu'au final c'était plus difficile à lire. De plus, on a tendance à vouloir mettre plusieurs lignes de ce genre là dans une même méthode de test. Cela augmente la granularité du test et empêche de donner un nom à chaque méthode de test
    @Test
    public void testBuildFullName_OneLiner() {
        assertThat(new PersonBuilder().withFirstName("Francois").withLastName("Wauquier").buildPerson().buildFullName()).isEqualTo("Francois WAUQUIER");
    }


Voici comment je préfère écrire un test aujourd'hui. Je me force à écrire au moins 3 lignes, et je place les lignes d'assertions dans un bloc de code anonyme. L'action est forcement la ligne avant le bloc.
    @Test
    public void testBuildFullName_BackToImplicitBDD() {
        Person person = new PersonBuilder().withFirstName("Francois").withLastName("Wauquier").buildPerson();
        String fullName = person.buildFullName();
        {
            assertThat(fullName).isEqualTo("Francois WAUQUIER");
        }
    }

 

Aucun commentaire:

Enregistrer un commentaire

Feedback...