tutrial pytest v1 fredericgaspoz 02.
2024
Tutorial pytest
Introduction
Pytest est un framework open source de tests unitaires pour le langage de programmation Python. Il
est utilisé pour écrire et exécuter des tests. C’est un outil intuitif et peu verbeux. Il sert à la fois à vérifier
le bon fonctionnement de fonctions individuelles et à effectuer des tests d'intégration élaborés qui
intègrent, par exemple, des bases de données et des API. Après avoir présenté succinctement
l’installation et le lancement d’un test, un exemple simple illustrera l’utilisation de pytest. La dernière
partie du document expose une bibliographie minimale.
Installation et lancement des tests
L’installation se fait simplement à l’aide de l’utilitaire pip : pip install pytest
Le code python implémentant les tests dois inclure pytest : import pytest
Le lancement d’un code de test se fait simplement en appelant le fichier contenant les fonctions de
tests. L’option -v augmente la verbosité du retour des tests.
pytest -v fichier_test.py
Convention de nommage des fonctions de test et des fichiers
Pytest exige que les noms des fonctions de test commencent par test. Les noms de fichiers sont libres.
Cependant, les fichiers dont le nom commence par test_ ou finit par _test , du répertoire courant,
sont automatiquement exécutés lorsque pytest est lancé sans indiquer un fichier particulier.
Exemple simple d’utilisation
Imaginons que notre programme nommé [Link] contienne une fonction nommée
distance_euclidienne servant à calculer la distance euclidienne entre deux points sur une carte.
import math
def distance_euclidienne(point1, point2):
return [Link]((point2[0] - point1[0])**2 + (point2[1] -
point1[1])**2)
Nous souhaitons tester1 notre fonction à l’aide de pytest. Dans un fichier nommé test_fct.py, nous
implémentons la fonction test_distance_euclidienne servant à tester la fonction
distance_euclidienne :
import pytest
import math
Fonction à tester
from fct import distance_euclidienne
def test_distance_euclidienne():
dist = distance_euclidienne([1,1],[3,3])
assert dist == [Link](8)
Valeur de vérification
1
Pour l’exemple, nous réalisons un test unitaire simpliste sur une fonction qui n’aurait pas besoin d’un test
unitaire.
1
tutrial pytest v1 fredericgaspoz 02.2024
La fonction distance_euclidienne appelée dans la fonction de test se voit imposer des paramètres
[1,1] et [3,3]. L’instruction assert permet de vérifier que le retour de la fonction testée correspond.
Le test étant valide, pytest retourne :
Paramètres des tests
Pytest permet de paramétrer les tests. En effet, une fonction de test peut s’exécuter plusieurs fois avec
différents ensembles de données. Cela facilite la vérification du comportement du code sous divers
scénarios sans avoir à écrire plusieurs tests.
La fonction de test test_param_distance_euclidenne est ajoutée dans le fichier de test. À l’aide
du décorateur @[Link], nous définissons en premier lieu avec «pt1,pt2,
output » les paramètres qui sont destinés à la fonction de test ; pt1 et pt2 pour les points, output
pour la sortie attendue. Puis, pour l’exemple, quatre scénarios sont testés.
@[Link]("pt1,pt2, output",
[([1,1],[3,3],8),
([1,2],[2,2],1), Scénarios
([2,3],[7,5],29), paramétrisés
([3,4],[5,6],8)])
def test_param_distance_euclidienne(pt1, pt2, output):
dist = distance_euclidienne(pt1,pt2)
assert dist == [Link](output)
La sortie de pytest est la suivante :
Nous pouvons constater que les quatre tests sont valides. A cela s’ajoute la première fonction de test
qui est toujours présente dans le fichier test_fct.py.
Fixture
Une fixture est une fonction que le framework exécute avant (et parfois après) les tests. Elle peut
configurer quelque chose avant qu'un test commence, comme préparer une base de données,
initialiser un environnement virtuel, fermer des connexions à une base de données ou supprimer des
fichiers temporaires. Une fonction « fixture » est déclarée à l’aide du décorateur : @[Link]
Comme exemple, nous créons une fixture dans le fichier test_fct.py valant la valeur retournée 8.
Celle-ci est exécutée une seule fois avant le lancement de la fonction de test qui l’utilise.
@[Link]
def input_value():
input = 8
return input
La fonction de test, pour utiliser la fixture, doit la passer en paramètre.
2
tutrial pytest v1 fredericgaspoz 02.2024
def test_distance_euclidienne(input_value):
dist = distance_euclidienne([1,1],[3,3])
assert dist == [Link](input_value)
En implémentant les fixtures dans un fichier nommé [Link], elles deviennent accessibles
depuis tous les fichiers de test. En effet, lorsque la fixture n’est pas dans le fichier de test lui-même,
pytest la cherche dans le fichier [Link].
@patch
Bien qu’appartenant à la bibliothèque [Link], le décorateur @patch est utilisé pour le
mocking2 dans les tests. Il sert à remplacer temporairement une méthode, une fonction, un objet ou
un attribut par un mock pendant la durée d'un test. L'argument passé à @patch est le chemin d'accès
à l'élément que nous souhaitons remplacer.
Dans cet exemple, @patch('[Link]') indique que sqrt dans le module math est remplacé par
un mock pour la durée de la fonction de test test_distance_euclidienne_patch. La fonction à
tester distance_euclidienne utilisera donc le mock en lieu et place de la véritable fonction. Le
mock retourne toujours la valeur 8. (mock_fct_sqrt.return_value)
Fonction from [Link] import patch
à mocker …
@patch('[Link]')
def test_distance_euclidienne_patch(mock_fct_sqrt):
mock_fct_sqrt.return_value = 8
dist = distance_euclidienne([1,1],[3,3]) Valeur de substitution
assert dist == 8
Groupement de tests
Lorsqu’un projet contient plusieurs fonctions de test, il est parfois nécessaire de grouper l’exécution
des tests.
Sélection avec le nom
Avec l’option -k suivi de <substring>, il est possible de lancer seulement les tests contenant dans
le nom de la fonction le <substring>.
pytest -k <substring> -v
Sélection avec un marqueur
Avec le décorateur @[Link].<markername>, il est possible d’ajouter un marqueur qui peut
être utilisé au lancement des tests.
pytest -m <markername> -v
Bibliographie
pytest, (s.d.), Full pytest documentation, [Link] consulté le
16 février 2024
Okken B., (2017), Python Testing with pytest: Simple, Rapid, Effective, and Scalable 1st Edition,
Pragmatic Bookshelf
2
Le «mocking» est une technique utilisée dans l’implémentation des tests pour simuler le comportement de
parties du système qui ne sont pas directement liées au test en cours.