Le TDD (Test Driven Development) est un process de développement logiciel qui consiste à faire évoluer un programme petit à petit à travers des mini-cycles : le développeur commence par implémenter un test automatique échoué représentant un cas d’utilisation particulier d’un nouveau code qu’il souhaite ajouter, et modifie ensuite le programme pour passer ce test. Puis, il implémente un deuxième test échoué d’un autre cas particulier de la même partie du code, et modifie le programme pour réussir les deux tests, et ainsi de suite jusqu’à l’obtention d’un programme qui passe plusieurs tests couvrant tous les cas d’utilisation du nouveau code. Ces tests sont ensuite conservés et lancés après toute modification du programme, afin de garantir la non-régression de toutes les fonctions de son code.
Application du TDD avec Pytest
Imaginons qu’on souhaite
implémenter un programme en python qui nous permet de valider une adresse email
et en suivant le TDD avec l’aide du framework pytest. On n’utilisera pas les
expressions régulières pour plus de lisibilité.
Dans notre cas, pour qu’une adresse mail soit valide il faut qu’elle ait la forme suivante : xxx@yyy.zzz Avec:
xxx est une chaine de caractère composée par des lettres et des chiffres et de taille minimale 1.
yyy et zzz sont de même que xxx mais de taille minimale 2.
Commençons par installer pytest avec la commande :
Après cela, créons un répertoire qui contiendra notre programme :
Ensuite, on crée un fichier pour le code et un autre pour les tests :
Commençons par définir une fonction de validation vide dans le fichier email_validation.py
Pour suivre les principes du TDD, on doit d’abord commencer par implémenter
un test de la fonction validate_email, un premier cas de test peut être que la
chaine “test@test.test” est bien une adresse valide :
Dans le fichier test_email_validation.py on peut implémenter le test comme suit :
Exécutons le test:
NB: pytest lance les fonctions préfixées par “test_” dans les fichiers préfixés par “test_”. Pour en savoir plus sur ces conventions aller sur ce lien
Comme décrit ci-dessus, on doit modifier le code le moins possible pour faire passer ce test.
Par exemple:
Maintenant si on lance pytest on obtient :
Et voilà ! On a terminé notre premier mini-cycle.
Recommençons la même démarche pour un deuxième tes. Ici, par exemple on rajoute le test qui vérifie que la chaine “abcd” n’est pas une adresse valide :
Et on lance pytest:
Pytest indique qu’un test passe et un test échoue, on appelle ce stade de cycle l’étape rouge.
La prochaine étape et de
modifier le code pour faire passer les deux tests. Par exemple vérifier que la
chaine passer en paramètre contient un caractère ‘@’ :
Maintenant les deux tests passent :
Troisième mini-cycle:
Test : test@@test.test n’est pas une adresse valide
Ensuite l’étape rouge et puis le nouveau code :
4ème mini-cycle :
Test : test@test n’est pas valide
Nouveau code :
On répète ensuite les mêmes
étapes avec des tests qui couvrent tous les cas d’utilisation de notre
programme:
test@test..test N’est pas valide
t@t.t N’est pas valide
t!@t?.t$ N’est pas valide
Enfin notre fichier de tests aura la forme suivante :
Et le fichier du code :
Quelques fonctionnalités avancées de pytest
1 - Paramétrer un test
Pytest permet de passer plusieurs entrées pour un scenario de test, cela peut se faire comme suit:
En lançant le test, on voit bien que 4 scenarios ont été executés :
2 - Grouper des tests
On peut grouper les tests sous plusieurs groupes en marquant chaque test avec le nom de son groupe et lancer un groupe de test en particulier.
Exemple :
Dans cet exemple on a distingué deux groupes de tests : les test des nombres numbers et les tests des chaines de caractères strings.
Pour lancer les tests des nombres uniquement la commande et la suivante :
3 - Les fixtures
Les fixtures sont des fonctions s’exécutant avant chaque test auquel elles sont appliquées, elles permettent de factoriser du code se répétant plusieurs fois dans les tests.
Exemple:
Quand les tests sont exécutés maintenant la variable threshold sera assignée avant chacun des deux tests :
Conclusion
Pour conclure, le TDD est
une approche de développement qui consiste à un avancement un lent mais sûr
tout au long du projet, cela permet d’optimiser la dette technique et d’éviter
les surprises de la production. Plusieurs frameworks aide à suivre cette méthodologie
tel que la libraire de tests standard unittest ou encore le framework pytest dont on a détaillé certaines fonctionnalités dans cet article, Il existe
encore plus de fonctionnalités de pytest que celles citées ci-dessus notament
pouvoir sauter des tests (skip), executer les tests en parallèle, arrêter
l’exécution des tests après un nombre d’echecs donné ...
Retrouvez l'ensemble de nos articles Python dans la catégorie dédiée. Et si vous souhaitez apprendre de nouvelles méthodologies de développement, retrouvez nos articles Agilité & Craft.