Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Le développement piloté par les tests

Après cette leçon: Je peux écrire un test qui échoue d’abord, le faire passer, puis ranger le code.

Leçon de 60 min9 commandesLab Linux du quotidien : la trentaine de commandes que les ingénieurs tapent de tête

Qu’est-ce que le développement piloté par les tests ?

Le développement piloté par les tests, ou TDD (Test-Driven Development), consiste à écrire d’abord un test qui échoue, puis le code qui le fait passer. On avance par petits pas, et chaque pas est protégé par un test.

Une boutique veut appliquer une remise à un prix. Plutôt que d’écrire toute la fonction d’un coup, on la fait grandir, un test après l’autre.

À la fin de cette leçon

Remarque

Je peux écrire un test qui échoue d’abord, le faire passer, puis ranger le code.

Mots-clés

MotCe que ça veut dire
TDDdéveloppement piloté par les tests : le test est écrit avant le code
Rougele moment où le nouveau test échoue
Vertle moment où tous les tests passent
Refactorisationranger le code sans changer ce qu’il fait
Petit pasle plus petit changement qui fait passer le test
Régressionun ancien test qui échoue à cause d’un changement récent

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Le cycle : rouge, vert, refactorisation

Le cycle a trois temps. Rouge : vous écrivez un test pour une fonction qui n’existe pas encore, et vous le voyez échouer.

Vert : vous écrivez juste assez de code pour que tous les tests passent. Refactorisation : vous rangez le code, les tests restent verts. Puis vous recommencez avec un nouveau test.

Pourquoi voir le test échouer d’abord ?

Un test que l’on n’a jamais vu échouer peut ne rien vérifier. En le voyant rouge, vous savez qu’il peut détecter une faute.

Les petits pas rendent aussi la recherche d’une faute facile. Si le test devient rouge, la cause est dans les quelques lignes que vous venez d’écrire.

Rouge : écrire le premier test

Commande
printf 'import unittest\nfrom remise import prix_remise\n\n\nclass TestsRemise(unittest.TestCase):\n    def test_dix_pour_cent(self):\n        self.assertEqual(prix_remise(1000, 10), 900)\n' > essais/test_remise.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Rouge : une ébauche qui rend 0

Commande
printf 'def prix_remise(prix, remise):\n    return 0\n' > essais/remise.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Rouge : le test échoue

Commande
python3 -m unittest discover -s essais -p "test_remise.py" 2>&1 | tail -1

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Vert : le plus petit code qui passe

Commande
printf 'def prix_remise(prix, remise):\n    return 900\n' > essais/remise.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Vert : le test passe

Commande
python3 -m unittest discover -s essais -p "test_remise.py" 2>&1 | tail -1

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Rendre 900 est un petit pas

La fonction rend toujours 900. C’est faux en général, mais c’est tout ce que le seul test sait demander.

Ce n’est pas une triche : c’est le plus petit pas. Un second test va obliger la fonction à calculer vraiment. Ajoutons-le : 2000 avec 50 % de remise doit donner 1000.

Rouge : ajouter un second test

Commande
printf '\n    def test_moitie_prix(self):\n        self.assertEqual(prix_remise(2000, 50), 1000)\n' >> essais/test_remise.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Rouge : le second test échoue

Commande
python3 -m unittest discover -s essais -p "test_remise.py" 2>&1 | tail -1

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Vert : calculer la remise

Commande
printf 'def prix_remise(prix, remise):\n    return prix - prix * remise // 100\n' > essais/remise.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Vert : les deux tests passent

Commande
python3 -m unittest discover -s essais -p "test_remise.py" 2>&1 | tail -1

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Ranger le code sans changer ce qu’il fait

Une fois vert, on range. Ici on peut donner aux variables des noms plus clairs. Les deux tests diront si on a cassé quelque chose.

La refactorisation ne change pas ce que fait le code. Elle ne se fait donc que lorsque tous les tests sont verts.

La fonction après rangement

Code: python
def prix_remise(prix_en_centimes, remise_en_pourcent):
    # La remise est calculée en centimes entiers, pour éviter les nombres décimaux.
    montant_remise = prix_en_centimes * remise_en_pourcent // 100
    return prix_en_centimes - montant_remise

assert prix_remise(1000, 10) == 900
assert prix_remise(2000, 50) == 1000
print("Les deux tests passent encore")

Erreur fréquente

Attention

Beaucoup pensent que le TDD veut dire écrire tous les tests d’abord. Au contraire : un seul test à la fois, puis le code, puis le suivant. Avec trop de tests rouges d’un coup, on ne sait plus par où commencer.

Faire grandir une fonction test par test

Dans le devoir, vous écrivez en_centimes(texte), qui lit un prix tel qu’on le tape en France, avec une virgule : "12,50" donne 1250.

Les règles arrivent par étapes, comme des tests. Pas de virgule : des euros entiers. Un seul chiffre après la virgule : des dizaines de centimes. Un texte qui n’est pas un prix : une erreur ValueError. Faites grandir votre fonction règle après règle.

À propos de ce labo et de sa source: Lab Linux du quotidien : la trentaine de commandes que les ingénieurs tapent de tête

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.