🧪 Python et le TDD#
Important
Avant de nous lancer dans les tests unitaires en python, il convient de créer la structure de projet suivante:
.
├── dna.py
└── tests
├── __init__.py
└── test_dna.py
2 directories, 3 files
Approche TDD en Python#
Nous voulons créer les fonctions suivantes:
Vérifier qu’une chaîne est bien un brin d’ADN valide
Obtenir le brin d’ADN complémentaire
Obtenir le nombre de codon
Indication

Pour rappel un brin d’ADN est constitué de 4 base azotée (A, T, G, C), organisé en codon de 3 bases. Ces bases fonctionnent par paires (d’où la structure en double hélice et c’est pour cela que l’on parle de brin d’ADN complémentaire). Ainsi A est complémentaire de T, et G est complémentaire de C.
GCGTCC
AGGGTG
ATCTAC
ATCTACCTCTTC
CTCTTC
CTXTEC
Unittest#
La bibliothèque standard Python est livrée avec un framework de test nommé unittest, que vous pouvez utiliser pour écrire des tests automatisés pour votre code.
Le package unittest
a une approche orientée objet dans laquelle les cas de test dérivent d’une classe de base, qui dispose de plusieurs méthodes utiles.
Ecriture de notre premier test#
Le package unittest
définit la classe TestCase, qui est principalement conçue pour écrire des tests unitaires.
Pour commencer à écrire nos cas de test, il suffit d’importer la classe et d’en hériter.
Les méthodes de tests ont leurs noms préfixer par test
. Ces méthodes testeront une unité de code donnée en utilisant différentes entrées et vérifieront les résultats attendus.
Nous allons ajouter à notre fichier test_dna.py
un premier test:
import unittest
class TestDNAFunctions(unittest.TestCase):
def test_valid_dna(self):
self.assertEqual(is_valid_dna("GCGTCC"), True)
Nous pouvons éxécuter notre premier test pour ce faire nous allons lancer la commande suivante dans notre console:
$ python3 -m unittest
Avertissement
Attention cette commande doit être lancée à la racine de notre projet.
Nous venons de respecter les deux premières étapes du TDD:
Créer un test et
Vérifier que celui-ci est en erreur étant donné qu’il n’y pas de code source.
Maintenant nous allons écrire juste assez de code pour que celui-ci passe.
Dans le fichier dna.py
, ajoutons le code de la fonction multiplication
def is_valid_dna(dna: str):
return all(base in ('A', 'T', 'C', 'G', 'X') for base in dna)
Et dans le fichier test_dna.py
ajoutons le code suivant:
from dna import is_valid_dna # Cette ligne permet d'importer la fonction is_valid_dna au sein de notre fichier de test
À faire
Et si on relance notre test maintenant ?
Pensez vous que notre jeu de test est suffisament fiable ?
Et si nous ajoutions une assertion à notre méthode test_valid_dna pour vérifier que
CTXTEC
est invalideQue se passe t’il lors de la relance de notre test ?
Pouvez-vous corriger cette erreur ?
Que se passe t’il lors de la relance de notre test ?
Félicitations, vous venez de découvrir les tests unitaires et le TDD !
Les classes héritées de TestCase
possédent une méthode setUp
et une méthode tearDown
. Elles sont respectivement exécutées avant l’appel de la méthode de test et après l’appel de la méthode de test (même si la méthode de test a levé une exception).
class ImportTestCase(unittest.TestCase):
def setUp(self):
# Do something before launching each test
def tearDown(self):
# Do something after calling each test
À faire
En respectant l’approche TDD, implémentez les deux fonctions restantes.
Indication
Pour aller plus loin je ne peux que vous recommander la lecture de la superbe documentation du module unittest.