Les tests unitaires sont une méthode de test des logiciels par laquelle des unités individuelles de code source sont soumises à divers tests afin de déterminer si elles sont aptes à être utilisées. Il détermine et assure la qualité de votre code.
En général, lorsque le processus de développement est terminé, le développeur code les critères, ou les résultats qui sont connus pour être potentiellement pratiques et utiles, dans le script de test pour vérifier l'exactitude d'une unité particulière. Au cours de l'exécution des cas de test, divers cadres enregistrent les tests qui échouent à un critère quelconque et les signalent dans un résumé.
Les développeurs sont censés rédiger des scripts de test automatisés, qui garantissent que chaque section ou unité est conforme à sa conception et se comporte comme prévu.
Tests unitaires Python
Bien que l'écriture de tests manuels pour votre code soit définitivement une tâche fastidieuse et chronophage, le cadre de test unitaire intégré à Python a rendu la vie beaucoup plus facile.
Le cadre de test unitaire de Python s'appelle unittest et est fourni avec Python.
Les tests unitaires permettent à votre code d'être à l'épreuve du temps puisque vous anticipez les cas où votre code pourrait potentiellement échouer ou produire un bogue. Bien que vous ne puissiez pas prévoir tous les cas, vous pouvez néanmoins traiter la plupart d'entre eux.
Une unité peut être classée en plusieurs catégories :
Un module entier,
Une fonction individuelle,
Une interface complète comme une classe ou une méthode.
La meilleure façon d'écrire des tests unitaires pour votre code est de commencer par la plus petite unité testable que votre code puisse avoir, puis de passer à d'autres unités et de voir comment cette plus petite unité interagit avec d'autres unités, de cette façon vous pouvez construire un test unitaire complet pour vos applications.
Le cadre de test unitaire de Python a été inspiré par le cadre de test unitaire de Java ( JUnit ) et présente des caractéristiques similaires à celles des principaux cadres de test unitaire d'autres langages. Le cadre de test unitaire de Python offre diversesfonctionnalitésnotamment :
Automatisation des tests
Partage du code d'installation et d'arrêt pour les tests
Agrégation des tests en collections
Indépendance des tests par rapport au cadre de présentation des rapports
Prenons maintenant un exemple et comprenons pourquoi vous avez besoin de tester votre code à l'unité.
Premiers pas avec Python unittest
Vous trouverez ci-dessous les étapes nécessaires à l'utilisation du cadre de Python unittest.
Création d'une fonction cube
Ecrivons un code pour calculer le volume d'un cube en Python
defcuboid_volume(l):return(l*l*l)
length =[2,1.1,-2.5,2j,'two']for i inrange(len(length)):print("The volume of cuboid:",cuboid_volume(length[i]))Propulsé par
The volume of cuboid: 8
The volume of cuboid: 1.3310000000000004
The volume of cuboid: -15.625
The volume of cuboid: (-0-8j)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-67e1c37a435f> in <module>
1 for i in range(len(length)):
----> 2 print ("The volume of cuboid:",cuboid_volume(length[i]))
<ipython-input-2-f50464fd88da> in cuboid_volume(l)
1 def cuboid_volume(l):
----> 2 return (l*l*l)
TypeError: can't multiply sequence by non-int of type 'str'Propulsé par
Analyse des résultats
Le résultat ci-dessus devrait vous donner une idée de l'importance de la mise en place d'un test unitaire pour votre code. Il y a trois choses qui sont certainement incorrectes dans le code ci-dessus :
Tout d'abord, le volume du parallélépipède est négatif,
Deuxièmement, le volume du cuboïde est un nombre complexe,
Enfin, le code aboutit à TypeError car vous ne pouvez pas multiplier une chaîne de caractères, qui n'est pas un indice.
Le troisième problème s'est heureusement soldé par une erreur, tandis que le premier et le deuxième ont réussi, bien que le volume du cuboïde ne puisse pas être négatif et qu'il s'agisse d'un nombre complexe.
Les tests unitaires sont généralement écrits sous la forme d'un code séparé dans un fichier différent, et il peut exister différentes conventions de dénomination que vous pouvez suivre. Vous pouvez écrire le nom du fichier de test unitaire sous la forme name of the code/unit + test séparé par un trait de soulignement ou test + name of the code/unit séparé par un trait de soulignement.
Par exemple, disons que le nom du fichier de code ci-dessus est cuboid_volume.py, alors le nom du code de votre test unitaire pourrait êtrecuboid_volume_test.py
Sans plus attendre, écrivons le test unitaire pour le code ci-dessus.
Utilisation de assertAlmostEqual
Tout d'abord, créons un fichier Python avec le nom volume_cuboid.py, qui contiendra le code de calcul du volume et le second avec le nom test_volume_cuboid.py, qui contiendra le code de test unitaire.
importationunittest
La classeTestCuboid hérite du moduleunittest, et dans cette classe, vous définissez diverses méthodes que vous voulez que votre test unitaire vérifie avec votre fonction cuboid_volume.
La première fonction que vous définirez est test_volume, qui vérifiera si la sortie de votre cuboid_volume est égale à ce que vous attendez. Pour ce faire, vous utiliserez la méthodeassertAlmostEqual.
Test 1
classTestCuboid(unittest.TestCase):deftest_volume(self):
self.assertAlmostEqual(cuboid_volume(2),8)
self.assertAlmostEqual(cuboid_volume(1),1)
self.assertAlmostEqual(cuboid_volume(0),0)
self.assertAlmostEqual(cuboid_volume(5.5),166.375)Propulsé par
Exécutons le script ci-dessus. Vous pouvez exécuter le module unittest en tant que script en spécifiant -m lors de son exécution.
!python -m unittest test_volume_cuboid.pyPropulsé par
Sortie :
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OKPropulsé par
C'est très bien ! Vous avez donc réussi à faire fonctionner votre premier code de test unitaire.
Le test s'est déroulé avec succès et a retourné OK, ce qui signifie que la fonction cuboid_volume fonctionne comme vous vous y attendez.
Test 2
Voyons ce qui se passe lorsque l'une des méthodesassertAlmostEqual échoue.
Remarquez que la dernière instruction assert a été modifiée.
!python -m unittest test_volume_cuboid.pyPropulsé par
Sortie :
F
======================================================================
FAIL: test_volume (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 15, in test_volume
self.assertAlmostEqual(cuboid_volume(5.5),0)
AssertionError: 166.375 != 0 within 7 places (166.375 difference)
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)Propulsé par
D'après la sortie ci-dessus, vous pouvez observer que la dernière instruction assert a donné lieu à un AssertionError, et donc à un échec du test unitaire. Le module de test unitaire de Python vous indique la raison de l'échec, ainsi que le nombre d'échecs de votre code.
Utilisation de assertRaises
Examinons maintenant une autre méthode d'affirmation, à savoir assertRaises, qui vous aidera à déterminer si votre fonction cuboid_volume traite correctement les valeurs d'entrée.
Supposons que vous souhaitiez tester si votre fonction cuboid_volume gère la classe ou le type d'entrée. Par exemple, si vous passez une chaîne de caractères en entrée, la fonction traitera-t-elle cette entrée comme une exception ou avec une condition if, puisque la longueur du cuboïde ne peut jamais être une chaîne de caractères.
!python -m unittest test_volume_cuboid.pyPropulsé par
Sortie :
F.
======================================================================
FAIL: test_input_value (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 17, in test_input_value
self.assertRaises(TypeError, cuboid_volume, True)
AssertionError: TypeError not raised by cuboid_volume
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)Propulsé par
C'est très bien ! Il est donc évident que votre code volume_cuboid.py ne prend pas correctement en compte les données qui lui sont transmises.
Modifier la fonction cube
Ajoutons une condition dans volume_cuboid.py pour vérifier si l'entrée ou la longueur du cuboïde est un booléen ou une chaîne de caractères et soulever une erreur.
!python -m unittest test_volume_cuboid.pyPropulsé par
Sortie :
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OKPropulsé par
Exécution du script de test Python dans le laboratoire Jupyter
Exécutons maintenant le script de test dans le laboratoire jupyter. Pour ce faire, vous devez d'abord définir le script de test dans le laboratoire jupyter, comme indiqué ci-dessous.
# -*- coding: utf-8 -*-"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""from volume_cuboid import*import unittest
classTestCuboid(unittest.TestCase):deftest_volume(self):
self.assertAlmostEqual(cuboid_volume(2),8)
self.assertAlmostEqual(cuboid_volume(1),1)
self.assertAlmostEqual(cuboid_volume(0),1)deftest_input_value(self):
self.assertRaises(TypeError, cuboid_volume,True)Propulsé par
Ensuite, vous utiliserez la méthodeunittest.main() pour exécuter le script de test, vous pouvez passer plusieurs arguments à la méthode ci-dessous, dont l'un est verbosity level.
Expérimentons différents niveaux de verbosité et voyons comment cela modifie la description de la sortie.
Verbosité 0
unittest.main(argv=[''],verbosity=0, exit=False)
Output:
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
<unittest.main.TestProgramat0x1de02774348>Propulsé par
Verbosité 1
unittest.main(argv=[''],verbosity=1, exit=False)
Output:
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgramat0x1de027a1cc8>Propulsé par
Verbosité 2
unittest.main(argv=[''],verbosity=2, exit=False)
Output:
test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgramat0x1de027a8308>Propulsé par
Visualisation de l'erreur d'assertion
Enfin, modifions le site final assertAlmostEqual dans la méthodetest_volume et analysons comment le niveau de verbosité 2 montrera l'échec de la méthode.
# -*- coding: utf-8 -*-"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""from volume_cuboid import*import unittest
classTestCuboid(unittest.TestCase):deftest_volume(self):
self.assertAlmostEqual(cuboid_volume(2),8)
self.assertAlmostEqual(cuboid_volume(1),1)
self.assertAlmostEqual(cuboid_volume(0),1)deftest_input_value(self):
self.assertRaises(TypeError, cuboid_volume,True)
unittest.main(argv=[''],verbosity=2, exit=False)Propulsé par
Sortie :
test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... FAIL
======================================================================
FAIL: test_volume (__main__.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<ipython-input-28-46ad33b909ee>", line 14, in test_volume
self.assertAlmostEqual(cuboid_volume(0),1)
AssertionError: 0 != 1 within 7 places (1 difference)
----------------------------------------------------------------------
Ran 2 tests in 0.003s
FAILED (failures=1)
<unittest.main.TestProgramat0x1de027b5448>Propulsé par
Résumé
Les résultats ci-dessus permettent de tirer les conclusions suivantes :
Le niveau de verbosité 0 indique simplement le nombre de tests effectués, c'est-à-dire 2 tests et le temps nécessaire à leur exécution,
Niveau de verbosité 1 ajouter deux points .. ce qui signifie que deux tests ont été exécutés,
Le niveau de verbosité 2 montre les noms détaillés des méthodes qui ont été exécutées ainsi que leur état OK ou FAIL.
Méthodes d'affirmation disponibles pour unittest
Le module de test unitaire de Python contient de nombreuses méthodes d'affirmation qui peuvent être utilisées pour vos tests.
Vous pouvez également apprendre à les connaître à l'aide du module Pydoc, qui est similaire à une fonction help en Python. Vous trouverez ci-dessous une démonstration de la manière dont vous pouvez utiliser le module Pydoc pour consulter la documentation de la méthodeassertCountEqual.
!python -m pydoc unittest.TestCase.assertCountEqualPropulsé par
Sortie :
Help on function assertCountEqual in unittest.TestCase:
unittest.TestCase.assertCountEqual = assertCountEqual(self, first, second, msg=None)
An unordered sequence comparison asserting that the same elements,
regardless of order. If the same element occurs more than once,
it verifies that the elements occur the same number of times.
self.assertEqual(Counter(list(first)),
Counter(list(second)))
Example:
- [0, 1, 1] and [1, 0, 1] compare equal.
- [0, 0, 1] and [0, 1] compare unequal.Propulsé par
Conclusion
Ce tutoriel était une introduction de base aux tests unitaires en Python et à leur importance en tant que développeur. Un bon exercice pour vous serait d'écrire un module de test unitaire pour l'un de vos anciens projets. Cela vous permettra d'acquérir une bonne expérience pratique de l'écriture de tests unitaires. Essayez également d'explorer les autres méthodes Assert. Pour en savoir plus sur les tests unitaires, consultez notretutoriel Pytest.
En tant que data scientist certifié, je suis passionné par l'utilisation des technologies de pointe pour créer des applications innovantes d'apprentissage automatique. Avec une solide expérience en reconnaissance vocale, en analyse de données et en reporting, en MLOps, en IA conversationnelle et en NLP, j'ai affiné mes compétences dans le développement de systèmes intelligents qui peuvent avoir un impact réel. En plus de mon expertise technique, je suis également un communicateur compétent, doué pour distiller des concepts complexes dans un langage clair et concis. En conséquence, je suis devenu un blogueur recherché dans le domaine de la science des données, partageant mes idées et mes expériences avec une communauté grandissante de professionnels des données. Actuellement, je me concentre sur la création et l'édition de contenu, en travaillant avec de grands modèles linguistiques pour développer un contenu puissant et attrayant qui peut aider les entreprises et les particuliers à tirer le meilleur parti de leurs données.
Découvrez les fonctions et méthodes des listes Python. Veuillez suivre les exemples de code pour list() et d'autres fonctions et méthodes Python dès maintenant.
Initiez-vous aux structures de données de Python : apprenez-en plus sur les types de données et les structures de données primitives et non primitives, telles que les chaînes de caractères, les listes, les piles, etc.
Tutoriel complet d'introduction aux boucles Python. Apprenez et pratiquez les boucles while et for, les boucles imbriquées, les mots-clés break et continue, la fonction range et bien plus encore.
Les tests unitaires sont une méthode de test des logiciels par laquelle des unités individuelles de code source sont soumises à divers tests afin de déterminer si elles sont aptes à être utilisées. Il détermine et assure la qualité de votre code.
En général, lorsque le processus de développement est terminé, le développeur code les critères, ou les résultats qui sont connus pour être potentiellement pratiques et utiles, dans le script de test pour vérifier l'exactitude d'une unité particulière. Au cours de l'exécution des cas de test, divers cadres enregistrent les tests qui échouent à un critère quelconque et les signalent dans un résumé.
Les développeurs sont censés rédiger des scripts de test automatisés, qui garantissent que chaque section ou unité est conforme à sa conception et se comporte comme prévu.
Tests unitaires Python
Bien que l'écriture de tests manuels pour votre code soit définitivement une tâche fastidieuse et chronophage, le cadre de test unitaire intégré à Python a rendu la vie beaucoup plus facile.
Le cadre de test unitaire de Python s'appelle
unittestet est fourni avec Python.Les tests unitaires permettent à votre code d'être à l'épreuve du temps puisque vous anticipez les cas où votre code pourrait potentiellement échouer ou produire un bogue. Bien que vous ne puissiez pas prévoir tous les cas, vous pouvez néanmoins traiter la plupart d'entre eux.
Une unité peut être classée en plusieurs catégories :
La meilleure façon d'écrire des tests unitaires pour votre code est de commencer par la plus petite unité testable que votre code puisse avoir, puis de passer à d'autres unités et de voir comment cette plus petite unité interagit avec d'autres unités, de cette façon vous pouvez construire un test unitaire complet pour vos applications.
Le cadre de test unitaire de Python a été inspiré par le cadre de test unitaire de Java (
JUnit) et présente des caractéristiques similaires à celles des principaux cadres de test unitaire d'autres langages. Le cadre de test unitaire de Python offre diverses fonctionnalitésnotamment :Prenons maintenant un exemple et comprenons pourquoi vous avez besoin de tester votre code à l'unité.
Premiers pas avec Python unittest
Vous trouverez ci-dessous les étapes nécessaires à l'utilisation du cadre de Python
unittest.Création d'une fonction cube
Ecrivons un code pour calculer le volume d'un cube en Python
Analyse des résultats
Le résultat ci-dessus devrait vous donner une idée de l'importance de la mise en place d'un test unitaire pour votre code. Il y a trois choses qui sont certainement incorrectes dans le code ci-dessus :
TypeErrorcar vous ne pouvez pas multiplier une chaîne de caractères, qui n'est pas un indice.Le troisième problème s'est heureusement soldé par une erreur, tandis que le premier et le deuxième ont réussi, bien que le volume du cuboïde ne puisse pas être négatif et qu'il s'agisse d'un nombre complexe.
Les tests unitaires sont généralement écrits sous la forme d'un code séparé dans un fichier différent, et il peut exister différentes conventions de dénomination que vous pouvez suivre. Vous pouvez écrire le nom du fichier de test unitaire sous la forme
name of the code/unit + testséparé par un trait de soulignement outest + name of the code/unitséparé par un trait de soulignement.Par exemple, disons que le nom du fichier de code ci-dessus est
cuboid_volume.py, alors le nom du code de votre test unitaire pourrait êtrecuboid_volume_test.pySans plus attendre, écrivons le test unitaire pour le code ci-dessus.
Utilisation de assertAlmostEqual
Tout d'abord, créons un fichier Python avec le nom
volume_cuboid.py, qui contiendra le code de calcul du volume et le second avec le nomtest_volume_cuboid.py, qui contiendra le code de test unitaire.importation unittest
La classe
TestCuboidhérite du moduleunittest, et dans cette classe, vous définissez diverses méthodes que vous voulez que votre test unitaire vérifie avec votre fonctioncuboid_volume.La première fonction que vous définirez est
test_volume, qui vérifiera si la sortie de votrecuboid_volumeest égale à ce que vous attendez. Pour ce faire, vous utiliserez la méthodeassertAlmostEqual.Test 1
Exécutons le script ci-dessus. Vous pouvez exécuter le module
unittesten tant que script en spécifiant-mlors de son exécution.Sortie :
C'est très bien ! Vous avez donc réussi à faire fonctionner votre premier code de test unitaire.
Le test s'est déroulé avec succès et a retourné
OK, ce qui signifie que la fonction cuboid_volume fonctionne comme vous vous y attendez.Test 2
Voyons ce qui se passe lorsque l'une des méthodes
assertAlmostEqualéchoue.Remarquez que la dernière instruction assert a été modifiée.
Sortie :
D'après la sortie ci-dessus, vous pouvez observer que la dernière instruction assert a donné lieu à un
AssertionError, et donc à un échec du test unitaire. Le module de test unitaire de Python vous indique la raison de l'échec, ainsi que le nombre d'échecs de votre code.Utilisation de assertRaises
Examinons maintenant une autre méthode d'affirmation, à savoir
assertRaises, qui vous aidera à déterminer si votre fonctioncuboid_volumetraite correctement les valeurs d'entrée.Supposons que vous souhaitiez tester si votre fonction
cuboid_volumegère la classe ou le type d'entrée. Par exemple, si vous passez une chaîne de caractères en entrée, la fonction traitera-t-elle cette entrée comme une exception ou avec une condition if, puisque la longueur du cuboïde ne peut jamais être une chaîne de caractères.Sortie :
C'est très bien ! Il est donc évident que votre code
volume_cuboid.pyne prend pas correctement en compte les données qui lui sont transmises.Modifier la fonction cube
Ajoutons une condition dans
volume_cuboid.pypour vérifier si l'entrée ou la longueur du cuboïde est un booléen ou une chaîne de caractères et soulever une erreur.Sortie :
Exécution du script de test Python dans le laboratoire Jupyter
Exécutons maintenant le script de test dans le laboratoire jupyter. Pour ce faire, vous devez d'abord définir le script de test dans le laboratoire jupyter, comme indiqué ci-dessous.
Ensuite, vous utiliserez la méthode
unittest.main()pour exécuter le script de test, vous pouvez passer plusieurs arguments à la méthode ci-dessous, dont l'un estverbosity level.Expérimentons différents niveaux de verbosité et voyons comment cela modifie la description de la sortie.
Verbosité 0
Verbosité 1
Verbosité 2
Visualisation de l'erreur d'assertion
Enfin, modifions le site final
assertAlmostEqualdans la méthodetest_volumeet analysons comment le niveau de verbosité 2 montrera l'échec de la méthode.Sortie :
Résumé
Les résultats ci-dessus permettent de tirer les conclusions suivantes :
OKouFAIL.Méthodes d'affirmation disponibles pour unittest
Le module de test unitaire de Python contient de nombreuses méthodes d'affirmation qui peuvent être utilisées pour vos tests.
Méthodes d'affirmation couramment utilisées
Source : documentation unittest
Contrôles de production
Les méthodes suivantes vous permettent de vérifier la production d'exceptions, d'avertissements et de messages de journal.
Source : documentation unittest
Méthodes spécifiques aux tâches
Source : documentation unittest
Pour connaître en détail les méthodes de
assert, consultez la documentation officielle de Python.Vous pouvez également apprendre à les connaître à l'aide du module
Pydoc, qui est similaire à une fonctionhelpen Python. Vous trouverez ci-dessous une démonstration de la manière dont vous pouvez utiliser le module Pydoc pour consulter la documentation de la méthodeassertCountEqual.Sortie :
Conclusion
Ce tutoriel était une introduction de base aux tests unitaires en Python et à leur importance en tant que développeur. Un bon exercice pour vous serait d'écrire un module de test unitaire pour l'un de vos anciens projets. Cela vous permettra d'acquérir une bonne expérience pratique de l'écriture de tests unitaires. Essayez également d'explorer les autres méthodes Assert. Pour en savoir plus sur les tests unitaires, consultez notre tutoriel Pytest.
Si vous débutez en Python et que vous souhaitez en savoir plus, suivez notre Introduction à la science des données en Python cours d'introduction à la science des données en Python.