Tdd

Développement dirigé par les tests

Test Driven Development 


Le Développement Dirigé par les Tests (TDD en anglais) est une technique de développement de logiciels se basant sur des cycles de développement intératifs très courts. 
 

Fonctionnement 

TDD

Fig. 1 : Principe du TDD


La Figure 1 présente le déroulement d'une itération de TDD : 

  1. Flèche rouge : Avant d'ajouter du code, nous devons écrire un test untaire qui échoue. Ceci permet de mettre en évidence le fait qu'il faut du nouveau code. Cette technique permet aussi de réfléchir sur le fonctionnement minimal attendu. 
  2. Flèche verte : A ce stade, le but est de faire passer les tests par tous les moyens. 
  3. Flèche bleue : Il faut alors nettoyer le code, que nous avons probablement écrit sans vraiment réfléchir. Nous devons alors supprimer la duplication et rendre le code le plus clair possible. 

Ce déroulement est à répéter encore et encore jusqu'à ce que tous les tests de la tâche courante (user story). En principe, tous les tests passent lorsque tous les critères voulus soient respectés. 
 


Règles du jeu 

Afin de faciliter ce type de développement, voici des règles à respecter : 

  • #1 : Ecrire du nouveau code uniquement si un test échoue
L'idée derrière cette règle est de n'écrire que le code qui est strictement nécessaire, pas plus. Cette pratique nous force à réfléchir à l'importance du code que nous souhaitons ajouter. 

  • #2 : Tester tout ce qui présente un "risque potentiel"
Il n'est pas possible de tout tester, c'est pourquoi nous parlons ici de risque potentiel. Toute fonctionnalité pouvant présenter une faille ou alors, s'il existe une spécificité du code que nous souhaitons mettre en valeur, doit avoir un test dédié. 
 


Exemple


Nous allons maintenant nous attaquer à un exemple concret pour être sûr que nous avons bien compris de quoi il est question ici. Le code source de cet exemple sera donné en Java

Nous voulons implémenter des comptes utilisateur pour des clients. Les fonctionnalités à tester sont les suivantes : 

  • Sauvegarder les nouveaux profils 
  • Assurer la non duplication des comptes
  • Vérification basique sur les informations données
La première étape à réaliser est l'écriture d'un test. Nous devons imaginer que le code existe déjà et que nous souhaitons simplement nous assurer de son bon fonctionnement : 


//Test
public void Create_Customer_Profile()
{
    // setup
    CustomerProfileManager manager = new CustomerProfileManager();
    // create a new customer profile
    CustomerProfile profile = new CustomerProfile("Scotty McLaren" , "Hagis");
    // confirm it does not exist in the database
    Assert.IsFalse(manager.Exists(profile.Id));
    // add it
    int uniqueId = manager.Add(profile); // get id from database
    profile.Id = uniqueId;
    // confirm it's been added
    Assert.IsTrue(manager.Exists(uniqueId));
    // clean up
    manager.Remove(uniqueId);
}

Ce test va permettre de tester l'ajout d'un nouveau profil utilisateur. Il est maintenant possible de passer à l'étape 2, l'écriture du code. 
Ici, ce qu'il faut écrire est plutôt évident : 

  1. ​Prendre les informations du profil utilisateur 
  2. Les enregistrer dans la base de données
Voici à quoi doit ressembler le code : 


public class CustomerProfileManager
{
    public int Add(CustomerProfile profile)
    {
        // pretend this code stored the profile
        // in the database, and returned a real id
        return 0;
    }
public bool Exists(int id) { // code to check if customer exists }
public void Remove(int id) { // code to remove a customer from the database } }
Il ne reste plus qu'à écrire le corps des fonctions. Une fois que c'est fait, le test passe. 

Il nous reste à présent l'étape de refactorisation. Il faut refactoriser le code du test, le code produit, les fichiers des configuration et tout autre fichier que nous aurions modifié. 

Une fois cette refactorisation effectuée, il faut se demander si d'autres tests sont nécessaires. Dans notre cas oui, il nous reste par exemple à tester qu'il n'est pas possible de dupliquer une entrée. 
Il nous faut donc répéter notre processus : écrire un test qui échoue, coder suffisamment pour le faire passer et enfin refactoriser. 

Parfois, on peut tomber sur le problème de l'oeuf ou la poule. En effet, il est parfaitement possible, au cours de l'écriture d'un test d'avoir besoin d'une fonctionnalité annexe du code. Pas de panique, il faut mettre le test courant en pause et s'attaquer au développement de la tâche annexe (en TDD bien entendu). Une fois que cette tâche est finie, nous pouvons reprendre notre autre développement. 
 


Conclusion 

Le principe fondamental du TDD est donc d'écrire le test, puis de le faire passer. Comme ce n'est pas, en général, ce que nous apprenons au cours d'une formation classique, nous pouvons avoir l'impression de faire les choses à l'envers. 

En refléchissant un peu plus, nous nous rendons rapidement compte que ce n'est pas le cas. En effet, n'est-ce pas une bonne idée pour créer un logiciel d'imaginer qu'il existe déjà ? C'est ce qui est fait en Développement Dirigé par les Tests.  
 


{{ message }}

{{ 'Comments are closed.' | trans }}