[PYTHON] Présentation de la fonction addModuleCleanup / doModuleCleanups de unittest

Tout en étudiant autour de python unittest et pytest, si vous regardez la traduction japonaise officielle de la documentation unittest, Puisqu'il y avait des fonctions addModuleCleanup et doModuleCleanups ajoutées à partir de python3.8, je les présenterai. Qu'est-ce que unittest? Il peut être préférable d'avoir un aperçu de unittest dans un autre article que de lire cet article.

TL;DR

Vous pouvez spécifier la fonction à appeler lorsqu'une erreur se produit avec la fonction setUpModule.

examen unittest

Par exemple, essayez d'exécuter le code suivant. Ceci est un test pour confirmer l'addition et la soustraction. Pour vérifier quand la fonction est en cours d'exécution

print(sys._getframe().f_code.co_name)Le nom de la fonction est émis à.



```python
import sys
import unittest

# TODO(hatsumi)~ J'ajouterai le code plus tard ~

def createConnection():
    print(sys._getframe().f_code.co_name)
#    raise Exception

def closeConnection():
    print(sys._getframe().f_code.co_name)

def setUpModule():
    createConnection()

def tearDownModule():
    closeConnection()

class TestOperator(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        print(sys._getframe().f_code.co_name)

    @classmethod
    def tearDownClass(self):
        print(sys._getframe().f_code.co_name)

    def setUp(self):
        print(sys._getframe().f_code.co_name)

    def tearDown(self):
        print(sys._getframe().f_code.co_name)

    def test_add(self):
        print(sys._getframe().f_code.co_name)
        self.assertEqual(2 + 3, 5)

    def test_sub(self):
        print(sys._getframe().f_code.co_name)
        assert 3 - 2 == 1


if __name__ == "__main__":
    unittest.main()

À la suite de l'exécution, les éléments suivants doivent être affichés.

createConnection
setUpClass
setUp
test_add
tearDown
.setUp
test_sub
tearDown
.tearDownClass
closeConnection

Vous pouvez voir que la configuration et le démontage sont appelés dans l'ordre de la méthode module-> classe->.

Sujet principal

Si une exception se produit dans la fonction setUpModule, la fonction tearDownModule ne sera pas appelée. Au lieu de cela, la fonction ajoutée par la fonction addModuleCleanup est exécutée par la fonction doModuleCleanups.

Dans le code ci-dessus, la fonction setUpModule génère createConnection et la fonction tearDownModule renvoie closeConnection. Si vous décommentez la fonction setUpModule et exécutez `` lever Exception '', la fonction tearDownModule ne sera pas appelée. Cela peut être bon si vous gérez le traitement des connexions à la base de données et des choses temporaires en supposant que la fonction tearDownModule est appelée.

la mise en oeuvre

Enregistrement d'une fonction

Afin d'exécuter la fonction, il est nécessaire d'enregistrer la fonction à l'avance. Pour ce faire, utilisez la fonction addModuleCleanup. Ajoutez le code suivant à la partie commentaire TODO du code ci-dessus. Enregistrez la fonction print_number.

def print_number():
    print(sys._getframe().f_code.co_name)

unittest.addModuleCleanup(print_number)

Lorsqu'une exception se produit à la suite de l'exécution, la fonction print_number est appelée. La chaîne de caractères est également affichée dans createConnection. ..

print_number
createConnection
E
======================================================================
ERROR: setUpModule (__main__)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_module.py", line 25, in setUpModule
    createConnection()
  File "test_module.py", line 19, in createConnection
    raise Exception
Exception

----------------------------------------------------------------------
Ran 0 tests in 0.001s

Enregistrement de plusieurs fonctions

Il est également possible d'enregistrer plusieurs fonctions. Cependant, dans ce cas, il sera exécuté par LIFO. Ajoutez le code suivant à la partie commentaire TODO du code ci-dessus.

unittest.addModuleCleanup((lambda : print('a')))
unittest.addModuleCleanup((lambda : print('b')))
unittest.addModuleCleanup((lambda : print('c')))

Résultat d'exécution

c
b
a
createConnection
E

Elle est enregistrée dans l'ordre a-> b-> c et sortie dans l'ordre c-> b-> a.

Exécution de la fonction enregistrée

La fonction enregistrée est exécutée par la fonction doModuleCleanups. Le pointu a peut-être remarqué que lors de l'exécution dans LIFO, il apparaît dans la liste. Donc, si vous exécutez d'abord la fonction doModuleCleanups, rien ne sera exécuté car la liste des fonctions à exécuter est un shell.

Ajoutez le code suivant à la partie commentaire TODO du code ci-dessus.

unittest.addModuleCleanup((lambda : print('a')))
unittest.addModuleCleanup((lambda : print('b')))
unittest.addModuleCleanup((lambda : print('c')))

unittest.case.doModuleCleanups()
print()

Résultat de sortie

c
b
a

createConnection
E

Une exception s'est produite après qu'une ligne a été libérée par print () ''. La fonction réenregistrée ne sera pas exécutée. De plus, bien qu'il s'agisse d'une fonction doModuleCleanups, `case``` est omis dans la documentation officielle, vous devriez donc l'appeler` `ʻunittest.case.doModuleCleanups ()`. (Mauvaise description?)

Résumé et côté

Il n'aurait dû y avoir aucun article individuel (au 4 mai 2020), alors j'en ai créé un. N'a-t-il pas l'impression que cette fonctionnalité n'est pas disponible dans pytest? J'espère que tu trouves cela utile.

Si vous êtes gentil, veuillez répondre aux questions suivantes ← ・ ・ ・

Lors de l'enregistrement de plusieurs fonctions, j'ai écrit à l'origine comme suit, Puisque l'id est le même, je produis lambda pour chaque abc comme l'article. Comment puis-je créer des instances individuelles ...? (Est-ce du Jamuripo en une seule ligne?)

#Avec cela, tous les 4 sont émis ...
for i in range(5):
    unittest.addModuleCleanup((lambda : print(i)))

URL

--Veuillez vous rendre au responsable pour une explication détaillée → https://docs.python.org/ja/3/library/unittest.html

Recommended Posts

Présentation de la fonction addModuleCleanup / doModuleCleanups de unittest
Présentation du framework BOT Minette pour Python
[Python] J'ai essayé de remplacer le nom de la fonction par le nom de la fonction
La première «fonction» GOLD
À propos de la fonction Déplier
La fonction d'affichage d'image d'iTerm est pratique lors du traitement d'images.