Comment écrire et exécuter des tests unitaires en Python à l’aide de PyTest
Lorsque vous écrivez du code en Python, il est important de vous assurer que votre code fonctionne comme prévu. L’une des meilleures façons de le faire est d’utiliser des tests unitaires, qui vous aident à vérifier si de petites parties (ou unités) de votre code fonctionnent correctement.
Dans cet article, nous allons apprendre à écrire et à exécuter des tests unitaires efficaces en Python à l’aide de PyTest, l’un des frameworks de test les plus populaires pour Python.
Que sont les tests unitaires ?
Les tests unitaires sont de petits tests simples qui se concentrent sur la vérification d’une seule fonction ou d’un petit morceau de code. Ils permettent de s’assurer que votre code fonctionne comme prévu et qu’il peut détecter les bogues à un stade précoce.
Des tests unitaires peuvent être écrits pour différentes parties de votre code, telles que des fonctions, des méthodes et même des classes. En écrivant des tests unitaires, vous pouvez tester votre code sans exécuter l’intégralité du programme.
Pourquoi utiliser PyTest ?
PyTest est un framework de test populaire pour Python qui facilite l’écriture et l’exécution de tests.
Il est simple à utiliser et possède de nombreuses fonctionnalités utiles telles que :
- Il vous permet d’écrire des cas de test simples et clairs.
- Il fournit des fonctionnalités avancées telles que des luminaires, des tests paramétrés et des plugins.
- Il fonctionne bien avec d’autres outils et bibliothèques de test.
- Il génère des résultats de test et des rapports faciles à lire.
Configuration de PyTest sous Linux
Avant de commencer à écrire des tests, nous devons installer PyTest. Si vous n’avez pas installé PyTest, vous pouvez l’installer à l’aide du gestionnaire de paquets Python appelé pip.
pip install pytest
Une fois PyTest installé, vous êtes prêt à commencer à écrire des tests !
Écrire votre premier test avec PyTest
Commençons par écrire une fonction simple, puis écrivons un test pour celle-ci.
Étape 1 : Écrire une fonction simple
Tout d’abord, créons une fonction Python que nous voulons tester. Supposons que nous ayons une fonction qui additionne deux nombres :
# add.py
def add(a, b):
return a + b
Il s’agit d’une fonction simple qui prend deux nombres a et b, les additionne et renvoie le résultat.
Étape 2 : Écrire un test pour la fonction
Maintenant, écrivons un test pour la fonction add. Dans PyTest, les tests sont écrits dans des fichiers séparés, généralement nommés test_*.py pour faciliter l’identification des fichiers de test.
Créez un fichier appelé test_add.py et écrivez le code de test suivant :
# test_add.py
from add import add
def test_add_numbers():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
Explication du code ci-dessus :
- Nous importons la fonction
addà partir du fichieradd.py. - Nous définissons une fonction de test appelée
test_add_numbers().Dans PyTest, une fonction de test doit commencer par le mottest_. - À l’intérieur de la fonction test, nous utilisons l’instruction
assertpour vérifier si le résultat de l’appel de la fonctionaddcorrespond à la valeur attendue. Si la condition de l’instructionassertestTrue, le test réussit ; sinon, il échoue.
Étape 3 : Exécutez le test
Pour exécuter le test, ouvrez votre terminal et accédez au répertoire où se trouve votre fichier test_add.py, puis exécutez la commande suivante :
pytest
PyTest trouvera automatiquement tous les fichiers de test (ceux qui commencent par test_) et exécutera les tests à l’intérieur de ceux-ci. Si tout fonctionne correctement, vous devriez voir une sortie comme celle-ci :
Le point (.) indique que le test a réussi. S’il y avait des problèmes, PyTest afficherait un message d’erreur.
Écrire des tests plus avancés
Maintenant que nous savons comment écrire et exécuter un test de base, explorons quelques fonctionnalités plus avancées de PyTest.
Test des exceptions attendues
Parfois, vous souhaitez tester si votre code lève les bonnes exceptions en cas de problème. Vous pouvez le faire avec la fonction pytest.raises().
Supposons que nous voulions tester une fonction qui divise deux nombres. Nous voulons lever une exception si le deuxième nombre est zéro (pour éviter les erreurs de division par zéro).
Voici la fonction de division :
# divide.py
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
Maintenant, écrivons un test pour cette fonction qui vérifie si le ValueError est levé lorsque nous essayons de diviser par zéro :
# test_divide.py
from divide import divide
import pytest
def test_divide_numbers():
assert divide(10, 2) == 5
assert divide(-10, 2) == -5
assert divide(10, -2) == -5
def test_divide_by_zero():
with pytest.raises(ValueError):
divide(10, 0)
Explication du code :
- Nous avons ajouté une nouvelle fonction de test appelée
test_divide_by_zero(). - À l’intérieur de cette fonction, nous utilisons
pytest.raises(ValueError)pour vérifier si uneValueErrorest levée lorsque nous appelons la fonction divide avec zéro comme deuxième argument.
Exécutez à nouveau les tests avec la commande pytest. Si tout fonctionne correctement, vous devriez voir ce résultat :
Utilisation des luminaires pour l’installation et le nettoyage
Dans certains cas, vous devrez peut-être configurer certaines conditions avant d’exécuter vos tests ou effectuer un nettoyage une fois les tests terminés. PyTest fournit des appareils pour y remédier.
Un dispositif est une fonction que vous pouvez utiliser pour mettre en place ou démonter les conditions de vos tests. Les fixtures sont souvent utilisés pour créer des objets ou se connecter à des bases de données nécessaires aux tests.
Voici un exemple d’utilisation d’un fixture pour configurer un répertoire temporaire afin de tester les opérations de fichier :
# test_file_operations.py
import pytest
import os
@pytest.fixture
def temporary_directory():
temp_dir = "temp_dir"
os.mkdir(temp_dir)
yield temp_dir # This is where the test will run
os.rmdir(temp_dir) # Cleanup after the test
def test_create_file(temporary_directory):
file_path = os.path.join(temporary_directory, "test_file.txt")
with open(file_path, "w") as f:
f.write("Hello, world!")
assert os.path.exists(file_path)
Explication du code :
- Nous définissons un fixture appelé
temporary_directoryqui crée un répertoire temporaire avant le test et le supprime par la suite. - La fonction
de test test_create_file()utilise ce fixture pour créer un fichier dans le répertoire temporaire et vérifie si le fichier existe.
Exécutez à nouveau les tests avec la commande pytest. PyTest détectera et utilisera automatiquement le luminaire.
Paramétrez vos tests avec Pytest
Parfois, vous souhaitez exécuter le même test avec des entrées différentes. PyTest vous permet de le faire facilement en utilisant paramétrement.
Supposons que nous voulions tester notre fonction d’addition avec plusieurs paires de nombres. Au lieu d’écrire des fonctions de test distinctes pour chaque paire, nous pouvons utiliser pytest.mark.parametrize pour exécuter le même test avec différentes entrées.
# test_add.py
import pytest
from add import add
@pytest.mark.parametrize("a, b, expected", [
(2, 3, 5),
(-1, 1, 0),
(0, 0, 0),
(100, 200, 300)
])
def test_add_numbers(a, b, expected):
assert add(a, b) == expected
Explication du code :
- Nous utilisons le décorateur
pytest.mark.parametrizepour définir plusieurs ensembles d’entrées (a,betattendu). - La
fonction de test test_add_numbers()s’exécutera une fois pour chaque ensemble d’entrées.
Exécutez à nouveau les tests avec la commande pytest, qui exécutera le test quatre fois, une fois pour chaque ensemble d’entrées.
Conclusion
Dans cet article, nous avons appris à écrire et à exécuter des tests unitaires efficaces en Python à l’aide de PyTest pour détecter les bogues à un stade précoce et s’assurer que votre code fonctionne comme prévu.
PyTest facilite l’écriture et l’exécution de ces tests, et grâce à ses fonctionnalités puissantes, vous pouvez gérer des besoins de test plus complexes au fur et à mesure que vous progressez dans votre parcours Python.

