Dans l'écosystème Python, le module unittest est l'outil standard pour structurer les tests unitaires. Une notion fondamentale pour garantir l'indépendance des tests est celle des "fixtures". Celles-ci permettent de préparer l'environnement avant l'exécution d'un test et de le nettoyer après.
Fixtures au niveau de l'instance : setUp et tearDown
Par défaut, lorsqu'une classe hérite de unittest.TestCase, elle peut définir les méthodes setUp() et tearDown(). Ces méthodes sont appelées systématiquement avant et après chaque méthode de test (toute méthode commençant par le préfixe test_).
import unittest
class TestFileProcessing(unittest.TestCase):
def setUp(self):
# Cette méthode s'exécute avant chaque test
print("\n--- Création d'un fichier temporaire ---")
self.temp_file = "data.tmp"
def tearDown(self):
# Cette méthode s'exécute après chaque test
print("--- Suppression du fichier temporaire ---")
self.temp_file = None
def test_write_operation(self):
print("Action : Test de l'écriture de données.")
def test_read_operation(self):
print("Action : Test de la lecture de données.")
if __name__ == '__main__':
unittest.main()
Dans l'exemple ci-dessus, si vous avez dix méthodes de test, le fichier temporaire sera créé et supprimé dix fois. Bien que cela garantisse une isolation parfaitte, cette approche devient problématique lorsque l'initialisasion est coûteuse en ressources (connexion à une base de données distante, initialisation d'un navigateur Web via Selenium, etc.).
Fixtures au niveau de la classe : setUpClass et tearDownClass
Pour optimiser les performances et éviter les répétitions inutiles, unittest propose les méthodes setUpClass() et tearDownClass(). Celles-ci ne sont exécutées qu'une seule fois pour l'ensemble de la classe de test.
Il est impératif de noter deux contraintes technqiues :
- Elles doivent être décorées avec
@classmethod. - Elles prennent l'argument
cls(la classe elle-même) au lieu deself.
import unittest
class TestAPIService(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Exécuté une seule fois au début
print(">>> Initialisation de la connexion API Gateway <<<")
cls.api_token = "ABC-123"
@classmethod
def tearDownClass(cls):
# Exécuté une seule fois à la fin
print(">>> Déconnexion et destruction de la session API <<<")
def test_get_user_profile(self):
print(f"Test : Récupération profil avec jeton {self.api_token}")
def test_update_settings(self):
print(f"Test : Mise à jour des paramètres avec jeton {self.api_token}")
if __name__ == '__main__':
unittest.main()
Tableau récapitulatif des différences
| Caractéristique | setUp / tearDown | setUpClass / tearDownClass |
|---|---|---|
| Fréquence | Avant/Après chaque test individuel. | Une seule fois par classe de test. |
| Décorateur | Aucun. | @classmethod obligatoire. |
| Argument | self (instance de la classe). |
cls (la classe elle-même). |
| Cas d'usage | Nettoyage de variables, reset de petits objets. | Connexions DB, chargement de gros fichiers, mocks réseaux. |