Cours Python en ligne
- Une introduction aux normes de codage PHP de WordPress • WPShout
- 8 choses que j'ai apprises Construire un site WordPress sans code • WPShout
- Étant donné quand-alors – Tests Python
- Le didacticiel WordPress essentiel pour les développeurs PHP • WPShout
- Je ne suis pas en podfading. Je ne suis pas! Je ne suis pas! Je ne suis pas!
Cet article contient des exemples sur la manière dont les fonctions et les méthodes de montage de test unittest sont écrites et dans quel ordre elles sont exécutées. Cela peut paraître long, mais c’est surtout des exemples de code et des exemples de sortie.
Je veux que ce soit une référence utile à la fois pour la syntaxe et le flux des appareils unittest.
Si j'ai oublié quelque chose, veuillez commenter ci-dessous et je mettrai à jour le post.
Contenu
Intro: Test de logiciels
Le terme appareils d'essai signifie vraiment deux choses.
Les équipements de test sont les ressources et les conditions initiales dont un test a besoin pour fonctionner correctement et indépendamment des autres tests.
La phrase a également pris de l'importance pour désigner les fonctions et les méthodes utilisées pour gérer les ressources et l'environnement.
Pour le reste de cet article, je parle vraiment des fonctions et des méthodes quand je dis agencements.
Les appareils de test sont des méthodes et des fonctions qui s'exécutent avant et après un test.
L'objectif est de fournir aux développeurs des points d'ancrage leur permettant de définir les conditions préalables requises pour le test, ainsi que le nettoyage après le test.
Dans de nombreux cas, il s'agira d'affecter, d'ouvrir ou de se connecter à une ressource de la configuration, et de désallouer, de fermer ou de se déconnecter dans la zone de décomposition.
Cependant, ce n’est que l’intention. Vous pouvez les utiliser vraiment comme vous le souhaitez.
Une bonne utilisation des fixtures est de configurer les structures ou les variables de la même manière pour tous les tests.
Cela permet de s'assurer que les tests peuvent être exécutés individuellement ainsi que dans un ensemble et dans n'importe quel ordre.
Exemple de cas commun
Les méthodes de montage les plus courantes sont setUp et tearDown.
Les méritent d'être les plus courantes, car ce sont elles qui permettent l'indépendance du test.
le installer()
la méthode s'exécute avant chaque test.
le abattre()
La méthode s'exécute après chaque test.
Voici du code.
importer unittest
import inspecter
Classe TestLists (unittest.TestCase):
def setUp (auto):
self.logPoint ()
self.myList = [1, 2, 3, 4]
def test_len (auto):
self.logPoint ()
self.assertEqual (len (self.myList), 4)
self.myList.append (-1)
self.assertEqual (len (self.myList), 5)
def test_min (auto):
self.logPoint ()
self.assertEqual (min (self.myList), 1)
def tearDown (auto):
self.logPoint ()
def logPoint (auto):
currentTest = self.id (). split ('.')[-1]
callFunction = inspect.stack ()[1][3]
print 'in% s -% s ()'% (currentTest, callingFunction)
1 2 3 4 5 6 7 8 9 dix 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
importation Test de l'unité importation inspecter classe TestListes(Test de l'unité.Cas de test): def installer(soi): soi.logPoint() soi.ma liste = [[[[1, 2, 3, 4] def test_len(soi): soi.logPoint() soi.affirmerEqual( len(soi.ma liste), 4 ) soi.ma liste.ajouter(–1) soi.affirmerEqual( len(soi.ma liste), 5 ) def test_min(soi): soi.logPoint() soi.affirmerEqual( min(soi.ma liste) , 1 ) def abattre(soi): soi.logPoint() def logPoint(soi): currentTest = soi.identifiant().Divisé('.')[[[[–1] appelantFonction = inspecter.empiler()[[[[1][[[[3] impression 'in% s -% s ()' % (currentTest, appelantFonction) |
Et voici la sortie.
> python -m unittest -q test_lists
dans test_len – setUp ()
dans test_len – test_len ()
dans test_len – tearDown ()
dans test_min – setUp ()
dans test_min – test_min ()
dans test_min – tearDown ()
————————————————– ——————–
A couru 2 tests en 0.032s
D'accord
> python –m Test de l'unité –q listes d'essais dans test_len – installer() dans test_len – test_len() dans test_len – abattre() dans test_min – installer() dans test_min – test_min() dans test_min – abattre() ––––––––––––––––––––––––––––––––––– Couru 2 tests dans 0.032s D'accord |
Notez que les tests sont emballés avec installer()
et abattre()
comme promis.
Flux de traçage avec logPoint ()
Dans le code ci-dessus, j’ai écrit une méthode utilitaire. logPoint ()
pour démontrer le flux de contrôle à travers le test.
Je suis sûr qu’il ya une manière plus propre de faire cela, mais je ne pourrais pas trouver une méthode plus propre.
Je ne vais pas décrire le inspecter module.
Cependant, il est bon de noter que j’utilise la id ()
méthode qui fait partie de unittest.TestCase
pour obtenir le nom du test en cours. Ceci est valable pendant la méthode de test, ainsi que setUp, tearDown et toutes les méthodes appelées à partir de la méthode de test.
Exemple de test complet
Bien que installer()
et abattre()
sont les méthodes qui nous permettent de nous assurer que chaque test peut être exécuté indépendamment et dans n’importe quel ordre, nous disposons également d’autres méthodes.
Je pense que ceci est une liste complète.
installer()
/ tearDown () `- avant et après les méthodes de testsetUpClass ()
/tearDownClass ()
– avant et après une classe de testssetUpModule ()
/tearDownModule ()
– avant et après un module de tests- Fonctions de nettoyage – méthodes supplémentaires tearDown pouvant être ajoutées au moment de l'exécution à toute méthode de test lors de la configuration ou lors de la méthode de test elle-même.
Voici du code avec tout sauf les fonctions de nettoyage.
importer unittest
import inspecter
def logPoint (contexte):
'fonction utilitaire utilisée pour les fonctions de module et les méthodes de classe'
callFunction = inspect.stack ()[1][3]
print 'in% s -% s ()'% (contexte, fonction d'appel)
def setUpModule ():
'appelé une fois, avant toute autre chose dans ce module'
logPoint ('module% s'% __name__)
def tearDownModule ():
'appelé une fois, après tout le reste de ce module'
logPoint ('module% s'% __name__)
class TestFixtures (unittest.TestCase):
@classmethod
def setUpClass (cls):
'appelé une fois, avant tout test'
logPoint ('class% s'% cls .__ name__)
@classmethod
def tearDownClass (cls):
'appelé une fois, après tous les tests, si setUpClass a réussi'
logPoint ('class% s'% cls .__ name__)
def setUp (auto):
'appelé plusieurs fois, avant chaque méthode de test'
self.logPoint ()
def tearDown (auto):
'appelé plusieurs fois, après chaque méthode de test'
self.logPoint ()
def test_1 (auto):
'un examen'
self.logPoint ()
def test_2 (auto):
'un autre test'
self.logPoint ()
def logPoint (auto):
'méthode utilitaire pour suivre le flux de contrôle'
callFunction = inspect.stack ()[1][3]
currentTest = self.id (). split ('.')[-1]
print 'in% s -% s ()'% (currentTest, callingFunction)
1 2 3 4 5 6 7 8 9 dix 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
importation Test de l'unité importation inspecter def logPoint(le contexte): 'fonction utilitaire utilisée pour les fonctions de module et les méthodes de classe' appelantFonction = inspecter.empiler()[[[[1][[[[3] impression 'in% s -% s ()' % (le contexte, appelantFonction) def setUpModule(): 'appelé une fois, avant toute autre chose dans ce module' logPoint('modules' % __prénom__) def tearDownModule(): 'appelé une fois, après tout le reste de ce module' logPoint('modules' % __prénom__) classe TestFixtures(Test de l'unité.Cas de test): @méthode de classe def setUpClass(cls): 'appelé une fois, avant tout test' logPoint('classe% s' % cls.__prénom__) @méthode de classe def tearDownClass(cls): 'appelé une fois, après tous les tests, si setUpClass a réussi' logPoint('classe% s' % cls.__prénom__) def installer(soi): 'appelé plusieurs fois, avant chaque méthode de test' soi.logPoint() def abattre(soi): 'appelé plusieurs fois, après chaque méthode de test' soi.logPoint() def test_1(soi): 'un examen' soi.logPoint() def test_2(soi): 'un autre test' soi.logPoint() def logPoint(soi): 'méthode utilitaire pour suivre le flux de contrôle' appelantFonction = inspecter.empiler()[[[[1][[[[3] currentTest = soi.identifiant().Divisé('.')[[[[–1] impression 'in% s -% s ()' % (currentTest, appelantFonction) |
Débit du dispositif de test complet
> python -m unittest -q unittest_fixtures.TestFixtures
dans le module unittest_fixtures – setUpModule ()
dans la classe TestFixtures – setUpClass ()
dans test_1 – setUp ()
dans test_1 – test_1 ()
dans test_1 – tearDown ()
dans test_2 – setUp ()
dans test_2 – test_2 ()
dans test_2 – tearDown ()
dans la classe TestFixtures – tearDownClass ()
dans le module unittest_fixtures – tearDownModule ()
————————————————– ——————–
A couru 2 tests en 0.026s
D'accord
> python –m Test de l'unité –q unittest_fixtures.TestFixtures dans module unittest_fixtures – setUpModule() dans classe TestFixtures – setUpClass() dans test_1 – installer() dans test_1 – test_1() dans test_1 – abattre() dans test_2 – installer() dans test_2 – test_2() dans test_2 – abattre() dans classe TestFixtures – tearDownClass() dans module unittest_fixtures – tearDownModule() ––––––––––––––––––––––––––––––––––– Couru 2 tests dans 0.026s D'accord |
Ajouter des appels de nettoyage
Supplémentaire nettoyer Des méthodes peuvent être ajoutées à partir d'une méthode test ou d'une méthode setUp.
Les fonctions de nettoyage sont appelées APRES tearDown () mais AVANT tearDownClass ()
Classe TestAddCleanup (TestFixtures):
def setUp (auto):
TestFixtures.setUp (auto)
# — ajouter un appareil de méthode de nettoyage pour tous les tests
def cleanup_a ():
self.logPoint ()
self.addCleanup (cleanup_a)
def test_1 (auto):
TestFixtures.test_1 (auto)
# — ajouter un appareil de méthode de nettoyage pour ce test seulement
def cleanup_b ():
self.logPoint ()
self.addCleanup (cleanup_b)
def test_2 (auto):
TestFixtures.test_1 (auto)
1 2 3 4 5 6 7 8 9 dix 11 12 13 14 15 16 17 18 19 |
classe TestAddCleanup(TestFixtures): def installer(soi): TestFixtures.installer(soi) # — ajouter un appareil de méthode de nettoyage pour tous les tests def nettoyage_a(): soi.logPoint() soi.addCleanup(nettoyage_a) def test_1(soi): TestFixtures.test_1(soi) # — ajouter un appareil de méthode de nettoyage pour ce test seulement def cleanup_b(): soi.logPoint() soi.addCleanup(cleanup_b) def test_2(soi): TestFixtures.test_1(soi) |
Sortie
> python -m unittest -q unittest_fixtures.TestAddCleanup
dans le module unittest_fixtures – setUpModule ()
dans la classe TestAddCleanup – setUpClass ()
dans test_1 – setUp ()
dans test_1 – test_1 ()
dans test_1 – tearDown ()
dans test_1 – cleanup_b ()
dans test_1 – cleanup_a ()
dans test_2 – setUp ()
dans test_2 – test_1 ()
dans test_2 – tearDown ()
dans test_2 – cleanup_a ()
dans la classe TestAddCleanup – tearDownClass ()
dans le module unittest_fixtures – tearDownModule ()
————————————————– ——————–
A couru 2 tests en 0.030s
D'accord
1 2 3 4 5 6 7 8 9 dix 11 12 13 14 15 16 17 18 19 |
> python –m Test de l'unité –q unittest_fixtures.TestAddCleanup dans module unittest_fixtures – setUpModule() dans classe TestAddCleanup – setUpClass() dans test_1 – installer() dans test_1 – test_1() dans test_1 – abattre() dans test_1 – cleanup_b() dans test_1 – nettoyage_a() dans test_2 – installer() dans test_2 – test_1() dans test_2 – abattre() dans test_2 – nettoyage_a() dans classe TestAddCleanup – tearDownClass() dans module unittest_fixtures – tearDownModule() ––––––––––––––––––––––––––––––––––– Couru 2 tests dans 0.030s D'accord |
Ignorer les tests dans setUp ()
Dans la méthode setUp, vous pouvez décider de passer un test.
Si ignoré, le test ne sera pas exécuté.
AUSSI, la méthode tearDown ne sera pas exécutée.
Classe TestSkip (TestFixtures):
def setUp (auto):
TestFixtures.setUp (auto)
currentTest = self.id (). split ('.')[-1]
si currentTest == 'test_2':
self.skipTest ('raison de sauter')
# la 'raison' sera affichée si l'indicateur '-v / – verbose' est utilisé
classe TestSkip(TestFixtures): def installer(soi): TestFixtures.installer(soi) currentTest = soi.identifiant().Divisé('.')[[[[–1] si currentTest == 'test_2': soi.skipTest('raison de sauter') # la 'raison' sera affichée si l'indicateur '-v / – verbose' est utilisé |
Sortie
> python -m unittest -q unittest_fixtures.TestSkip
dans le module unittest_fixtures – setUpModule ()
dans la classe TestSkip – setUpClass ()
dans test_1 – setUp ()
dans test_1 – test_1 ()
dans test_1 – tearDown ()
dans test_2 – setUp ()
dans la classe TestSkip – tearDownClass ()
dans le module unittest_fixtures – tearDownModule ()
————————————————– ——————–
A couru 2 tests en 0.018s
OK (ignoré = 1)
> python –m Test de l'unité –q unittest_fixtures.TestSkip dans module unittest_fixtures – setUpModule() dans classe TestSkip – setUpClass() dans test_1 – installer() dans test_1 – test_1() dans test_1 – abattre() dans test_2 – installer() dans classe TestSkip – tearDownClass() dans module unittest_fixtures – tearDownModule() ––––––––––––––––––––––––––––––––––– Couru 2 tests dans 0.018s D'accord (sauté=1) |
Exceptions dans les fixtures
Dans tous les exemples ci-dessus, les montages de test sont très simples et rien ne peut mal tourner.
Cependant, ce n’est pas toujours le cas, bien sûr.
Il est important de comprendre ce qui se passe dans votre flux de contrôle en cas de défaillance d’un dispositif de test.
Que se passe-t-il si une fonction de montage de test frappe une assertion ou une exception?
Cela dépend de la méthode / fonction de l'appareil.
Mais…. c’est un sujet pour un autre post.
Plus précisément, que se passe-t-il lorsque les appareils les plus modestes échouent
Commentaires, s'il vous plaît
J'espère que cela a été instructif et j'espère que ce sera une référence précieuse pour la syntaxe et le flux de fonctions et méthodes untestest.
Si cela est utile, j'aimerais vraiment savoir. S'il vous plaît laissez un commentaire.
La rétroaction me permet de continuer.
À votre santé.
[ad_2]