Unittest est le framework de test fourni par défaut avec Python. Vous avez pu voir dans le chapitre précédent comment mettre en place des tests unitaires à l’aide du framework Pytest. Nous allons maintenant voir comment faire la même chose avec Unittest. Ne vous inquiétez pas, il n’y a presque pas de différence.
Comme pour Pytest, il faudra aussi définir une fonction qui contiendra le scénario et les assertions qui permettent de valider le test. De plus, l’organisation des fichiers de tests dans le projet restera identique. Jusque-là, il n’y a pas de changement.
Contrairement à Pytest, les tests doivent être codés dans une classe héritant de la classeTestCase
du module Unittest. Les scénarios seront implémentés comme des méthodes de cette classe.
De plus, pour exécuter l’ensemble des tests du module, nous devons appeler la fonctionmain
du moduleunittest
. Ainsi, pour lancer l’ensemble des tests, nous devons ajouter à la fin du fichier unmain
avec l’appel de la fonctionunittest.main()
.
if __name__ == "__main__":
unittest.main()
D’autre part, la classeTestCase
fournit un ensemble de méthodes permettant de réaliser nos assertions. Voici les plus communes :
Méthode | Vérifie que |
assertEqual(a, b) | a == b |
assertNotEqual(a, b) | a != b |
assertTrue(a) | bool(a) is True |
assertFalse(a) | bool(a) is False |
assertIs(a, b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(a) | a is None |
assertIsNotNone(a) | a is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsIntance(a, b) | not isinstance(a, b) |
Une fois l'implémentation des tests terminée, vous pouvez exécuter une des commandes suivantes sur le terminal pour lancer les tests. Supposons que le fichier de test s’appellenom_du_fichier.py
:
Un module de test :
python -m unittest nom_du_fichier
python nom_du_fichier.py
Un scénario spécifique dans un module de test :
python -m unittest nom_du_fichier.<nom du test>
L’ensemble des modules de test contenus dans un répertoire :
python -m unittest discover <nom du répertoire de test>/
Voici le résumé des différentes étapes pour implémenter un test :
Importez le module
unittest
en haut du fichier de test.Créez la classe de test, la classe fille de
unittest.TestCase
.Implémentez votre scénario en créant une méthode commençant par “test”.
Ajoutez le
main
à la fin du fichier.Lancez la commande adaptée à votre situation sur le terminal.
Écrivons maintenant un test à l’aide du framework Unittest. Dans cet exemple, nous allons créer différents scénarios qui vérifieront des méthodes de la classeString
dans le fichiertest_string.py
:
import unittest
class TestString(unittest.TestCase):
def test_should_capitalize_string(self):
string = "hello"
expected_value = "Hello"
self.assertEqual(string.capitalize(), expected_value)
def test_should_upper_string(self):
string = "hello"
expected_value = "HELLO"
self.assertEqual(string.upper(), expected_value)
def test_should_trim_string(self):
string = " hello "
expected_value = "hello"
self.assertEqual(string.strip(), expected_value)
if __name__ == "__main__":
unittest.main()
Une fois l’implémentation des tests terminée, nous pouvons lancer la commandepython -m unittest test_string
dans le terminal afin d’exécuter les tests et vérifier le résultat :
Nous pouvons voir dans la sortie de la console qu’il y a eu effectivement trois tests qui ont été exécutés (Ran 3 tests in 0.000s
) et validés grâce au mot-cléOK
.
Je vais maintenant délibérément mettre une erreur sur le premier test qui permet de convertir la première lettre en majuscule. Ainsi, nous allons spécifier la valeur attendue avec un “h” minuscule. Nous allons pouvoir voir comment l’erreur est indiquée sur le terminal. Voici le résultat :
Cette capture d’écran contient plusieurs points à souligner. Je vais vous traduire les lignes importantes afin de débugger facilement vos tests :
F..
: la première ligne avec la lettreF
indique que le premier test n’est pas valide. Les deux points..
indiquent que les deux autres tests sont valides.FAIL: test_should_capitalize_string
: indique le nom du test qui n’est pas valide.self.assertEqual(string.capitalize(), expected_value)
: indique l’assertion qui a été soulevée au niveau du code.AssertionError: 'Hello' != 'hello'
: montre qu’il y a bien une différence entre le résultat et la valeur attendue dans le test. Dans les lignes suivantes, nous avons une indication plus détaillée de l’erreur.FAILED (failures=1)
: la dernière ligne indique que la validation des tests du module a échoué et qu’il y a un test qui n’est pas valide.
Dans ce screencast, nous allons voir comment mettre en place vos premier tests avec le framework Unittest :
À vous de jouer !
Reprenons le projet de la calculatrice et le même plan de test, pour ajouter l’ensemble des tests unitaires avec le framework de test Unittest.
Votre mission :
Ajoutez un package de tests qui contiendra l’arborescence de test.
Créez la suite de tests concernant le module view avec Unittest.
Créez la suite de tests concernant le module operators avec Unittest.
Vous pouvez commencer par mettre en place le test que je présente dans la vidéo ci-dessous. Je mets en place un test qui permet de vérifier que l’addition fonctionne correctement dans le cas nominal.
Retrouvez une proposition de correction sur GitHub !
En résumé
Avec le framework de test Unittest, les scénarios seront implémentés dans une classe héritant de
TestCase
et comme des méthodes de cette classe.Unittest fournit un ensemble de méthodes permettant de réaliser nos assertions.
Il faut ajouter le
main
de Unittest à la fin du fichier.Lancez les tests d’un module de test à l’aide de la commande
python -m unittest <nom du module de test>
. Il existe d'autres commandes pour affiner le lancement des tests.
Vous avez appris plein de choses dans cette première partie. Il est maintenant temps de tester vos connaissances à l’aide d’un petit quiz. Bonne chance !