[PYTHON] Einführung der Funktion addModuleCleanup / doModuleCleanups von unittest

Wenn Sie sich die offizielle japanische Übersetzung der unittesten Dokumentation ansehen, während Sie sich mit Python unittest und pytest befassen, Da ab Python3.8 die Funktionen addModuleCleanup und doModuleCleanups hinzugefügt wurden, werde ich sie vorstellen. Was ist unittest? Es ist möglicherweise besser, sich in einem anderen Artikel einen Überblick über unittest zu verschaffen, als diesen Artikel zu lesen.

TL;DR

Sie können die Funktion angeben, die aufgerufen werden soll, wenn mit der Funktion setUpModule ein Fehler auftritt.

unittest Bewertung

Versuchen Sie beispielsweise, den folgenden Code auszuführen. Dies ist ein Test zur Bestätigung der Addition und Subtraktion. Überprüfen, wann die Funktion ausgeführt wird

print(sys._getframe().f_code.co_name)Der Funktionsname wird bei ausgegeben.



```python
import sys
import unittest

# TODO(hatsumi)~ Ich werde den Code später hinzufügen ~

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()

Als Ergebnis der Ausführung sollte Folgendes ausgegeben werden.

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

Sie können sehen, dass Setup und Teardown in der Reihenfolge Modul-> Klasse-> Methode aufgerufen werden.

Hauptthema

Wenn in der Funktion setUpModule eine Ausnahme auftritt, wird die Funktion tearDownModule nicht aufgerufen. Stattdessen wird die von der Funktion addModuleCleanup hinzugefügte Funktion von der Funktion doModuleCleanups ausgeführt.

Im obigen Code gibt die Funktion setUpModule createConnection aus und die Funktion tearDownModule gibt closeConnection aus. Wenn Sie die Funktion setUpModule auskommentieren und `` `erhöhen Ausnahme``` ausführen, wird die Funktion tearDownModule nicht aufgerufen. Es kann hilfreich sein, wenn Sie die Verarbeitung von Datenbankverbindungen und temporären Dingen unter der Annahme verwalten, dass die Funktion tearDownModule aufgerufen wird.

Implementierung

Registrierung einer Funktion

Um die Funktion auszuführen, muss die Funktion im Voraus registriert werden. Verwenden Sie dazu die Funktion addModuleCleanup. Fügen Sie dem TODO-Kommentarteil des obigen Codes den folgenden Code hinzu. Registrieren Sie die Funktion print_number.

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

unittest.addModuleCleanup(print_number)

Wenn aufgrund der Ausführung eine Ausnahme auftritt, wird die Funktion print_number aufgerufen. Die Zeichenfolge wird auch in createConnection angezeigt. ..

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

Registrierung mehrerer Funktionen

Es ist auch möglich, mehrere Funktionen zu registrieren. In diesem Fall wird es jedoch von LIFO ausgeführt. Fügen Sie dem TODO-Kommentarteil des obigen Codes den folgenden Code hinzu.

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

Ausführungsergebnis

c
b
a
createConnection
E

Es wird in der Reihenfolge a-> b-> c registriert und in der Reihenfolge c-> b-> a ausgegeben.

Ausführung der registrierten Funktion

Die registrierte Funktion wird von der Funktion doModuleCleanups ausgeführt. Der Scharfe hat vielleicht bemerkt, dass es beim Ausführen in LIFO aus der Liste herausspringt. Wenn Sie also zuerst die Funktion doModuleCleanups ausführen, wird nichts ausgeführt, da die Liste der auszuführenden Funktionen eine Shell ist.

Fügen Sie dem TODO-Kommentarteil des obigen Codes den folgenden Code hinzu.

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

unittest.case.doModuleCleanups()
print()

Ausgabeergebnis

c
b
a

createConnection
E

Eine Ausnahme tritt auf, nachdem eine Zeile durch `print ()` freigegeben wurde. Die erneut registrierte Funktion wird nicht ausgeführt. Obwohl es sich um eine doModuleCleanups-Funktion handelt, wird "case" in der offiziellen Dokumentation weggelassen. Sie sollten sie daher "unittest.case.doModuleCleanups ()" nennen. (Falsche Beschreibung?)

Zusammenfassung und beiseite

Es sollte keine einzelnen Artikel geben (Stand: 4. Mai 2020), also habe ich einen erstellt. Fühlt es sich nicht so an, als ob diese Funktion in pytest nicht verfügbar ist? Ich hoffe, Sie finden es nützlich.

Wenn Sie nett sind, beantworten Sie bitte die folgenden Fragen ← ・ ・ ・

Bei der Registrierung mehrerer Funktionen habe ich ursprünglich wie folgt geschrieben: Da die ID dieselbe ist, gebe ich Lambda für jeden ABC wie den Artikel aus. Wie kann ich einzelne Instanzen erstellen ...? (Ist es einzeiliger Jamuripo?)

#Damit werden alle 4 ausgegeben ...
for i in range(5):
    unittest.addModuleCleanup((lambda : print(i)))

URL

Recommended Posts

Einführung der Funktion addModuleCleanup / doModuleCleanups von unittest
Einführung in das BOT-Framework Minette für Python
[Python] Ich habe versucht, den Funktionsnamen durch den Funktionsnamen zu ersetzen
Die erste GOLD "Funktion"
Informationen zur Entfaltungsfunktion
Die Bildanzeigefunktion von iTerm ist praktisch bei der Verarbeitung von Bildern.