Je vous ai plusieurs fois parlé des tests au long de ce cours, mais nous n’avons pas vraiment de bonne manière de les lancer. Voyons alors ce que propose Python pour ça.
Pytest
Pytest est une bibliothèque tierce fréquemment utilisée pour l’écriture de tests en Python, par la simplicité avec laquelle elle permet de décrire les cas de tests.
Premièrement vous pouvez installer Pytest avec la commande pip install pytest
.
Celle-ci installe l’utilitaire pytest
dans l’environnement courant.
Ensuite, il suffit d’utiliser la commande pytest
, seule ou accompagnée de fichiers ou répertoires en arguments (par défaut il explorera le répertoire courant).
Pytest se charge d’identifier les fichiers de tests, qui sont les fichiers Python préfixés de test_
.
À l’intérieur de ces fichiers, les fonctions avec ce même préfixe sont identifiées comme des fonctions de tests.
Ainsi, les modules de tests que vous nous avons écrits précédemment, contenant des fonctions de tests formées d’assertions, sont déjà compatibles avec Pytest.
% pytest test_operations.py
======================== test session starts ========================
platform linux -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /home/antoine
collected 2 items
test_operations.py .. [100%]
========================= 2 passed in 0.01s =========================
Tout se passe bien, nos fonctions valident les tests ! En cas d’erreur, Pytest s’arrête à la première assertion fausse de la fonction et affiche un rapport explicite du problème.
======================== test session starts ========================
platform linux -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /home/antoine
collected 2 items
test_operations.py F. [100%]
============================== FAILURES =============================
___________________________ test_addition ___________________________
def test_addition():
assert addition(3, 5) == 8
assert addition(1, 0) == 1
> assert addition(5, -8) == 3
E assert -3 == 3
E + where -3 = addition(5, -8)
test_operations.py:7: AssertionError
====================== short test summary info ======================
FAILED test_operations.py::test_addition - assert -3 == 3
==================== 1 failed, 1 passed in 0.02s ====================
Pytest permet d’aller plus loin que ça, et fournit des outils pour paramétrer facilement nos tests (générer différentes valeurs en entrée), abstraire les entrées et sorties standards (pour tester des fonctions qui utiliseraient print
ou input
) et bien d’autres encore que vous découvrirez dans sa documentation.
Unittest
Unittest est le module de la bibliothèque standard dédié à l’écriture de tests. Je ne vous en ai pas parlé jusqu’ici parce que celui-ci nécessite l’écriture de classes, qui ne sont abordées que dans le cours sur la programmation orientée objet en Python.
On peut en apprendre plus sur la page de documentation du module et on découvre notamment quelle structure respecter pour écrire une suite de tests.
Il faut ainsi écrire une classe TestFooBar
1 que l’on indique comme étant un cas de test (via unittest.TestCase
entre parenthèses, qui signifie que notre classe dérive de TestCase
) à l’interieur de laquelle on place nos fonctions de tests.
Ces fonctions possèdent un paramètre spécial self
qui sera fourni automatiquement.
Cet objet self
possède différentes méthodes, notamment assertEqual
pour vérifier que les deux arguments sont égaux, assertTrue
qui revient à faire une assertion et assertFalse
pour l’inverse (vérifier qu’une expression est fausse).
On peut exécuter un fichier de tests à l’aide de la commande python -m unittest
.
% python -m unittest test_operations.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
En cas d’erreur(s), celles-ci sont aussi signalées par le programme.
% python -m unittest test_operations.py
F.
======================================================================
FAIL: test_addition (test_operations.TestOperations)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/antoine/test_operations.py", line 10, in test_addition
self.assertEqual(addition(5, -8), 3)
AssertionError: -3 != 3
----------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (failures=1)
- Il est coutume d’utiliser un style CamelCase, où les différents mots qui forment le nom sont écrits avec une majuscule et ne sont pas séparés d'underscores.↩