Python assert Ausnahme
- Verwenden des Kontext-Managers zum Abfangen von Python assert Ausnahmen
- Verwenden von Schlüsselwortargumenten zum Abfangen von Python-Assert-Ausnahmen
Dieser Artikel bringt einem zum Verständnis von assert
als Testeinheit, um zu testen, ob die Funktionen Ausnahmen (Fehler, die während der Codeausführung erkannt werden) auslösen können, ohne die Ausführung unbedingt zu beenden. Mit anderen Worten, die ausgelöste Ausnahme ist gekapselt.
Dieser Test wird bestanden, wenn eine Ausnahme ausgelöst wird. Ein Fehler wird ausgelöst, wenn eine andere Ausnahme als die erwartete ausgelöst wird. In einem Fall, in dem überhaupt keine Ausnahme ausgelöst wird, schlägt der Test fehl.
Verwenden des Kontext-Managers zum Abfangen von Python assert Ausnahmen
Ähnlich wie es im allgemeinen Python-Konzept die Zuweisung und Freigabe von Ressourcen ermöglicht, wenn sie unbedingt erforderlich sind, erfasst der Kontext hier das tatsächliche Ausnahmeobjekt, das während des Tests ausgelöst wird.
Es speichert dieses Ausnahmeattribut im Objekt, wenn eine zusätzliche Leistungsprüfung der ausgelösten Ausnahme erforderlich ist.
Um zu testen, ob eine Funktion fehlschlägt oder besteht, ob eine Ausnahme ausgelöst wird oder nicht, verwenden wir TestCase.assertRaises
aus dem Modul unittest
.
Sehen wir uns ein praktisches Beispiel mit dem Kontextmanager an.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
Ausgabe:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Im Beispielcode ist der Test erfolgreich, da wir erwarten, dass eine Ausnahme ausgelöst wird. Wir teilen 5 durch eine undefinierte Variable someNumber
. Daher löst die Funktion eine NameError
-Ausnahme aus. Daher besteht unser Test, wie durch das .
in der ersten Zeile der Ausgabe angezeigt wird.
Sehen wir uns ein Beispiel an, bei dem der Test fehlschlägt, wenn keine Ausnahme ausgelöst wird.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
someNumber = 10
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
Ausgabe:
F
======================================================================
FAIL: test_nameerror (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example
Articles\Article Requirement Spec
and Example Articles\fah.py", line 106, in test_nameerror
100 * (someNumber/5)
AssertionError: Exception not raised
----------------------------------------------------------------------
Ran 1 test in 0.002s
FAILED (failures=1)
In diesem Beispielcode definieren wir einen Wert für someNumber
und führen dann den arithmetischen Ausdruck damit aus.
Die Ausgabe zeigt uns, dass der Test wie erwartet fehlschlägt. Wir erwarten diesmal keine NameError
-Ausnahme, da ein definierter Wert für someNumber
existiert.
Wir können den Kontextmanager auch mit benutzerdefinierten Ausnahmen wie im folgenden Beispiel implementieren.
import unittest
def user_function():
raise Exception("A user-defined exception")
class MyTestCase(unittest.TestCase):
def test_userexception(self):
with self.assertRaises(Exception) as context:
user_function()
self.assertTrue("A user-defined exception" in str(context.exception))
if __name__ == "__main__":
unittest.main()
Ausgabe:
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
Denken Sie daran,
str
zu verwenden, um diecontext.exception
einzuschließen, um einen TypeError zu vermeiden.
Wir stellen assertTrue
vor, eine unittest
-Bibliothek, die beim Unit-Test einen Testwert mit true vergleicht.
Anstelle von assertTrue können Sie auch assertIn
verwenden.
Beispiel:
import unittest
def user_function():
raise Exception("A use defined exception")
class MyTestCase(unittest.TestCase):
def test_userexception(self):
with self.assertRaises(Exception) as context:
user_function()
self.assertIn("A use defined exception", str(context.exception))
if __name__ == "__main__":
unittest.main()
Wir sehen die gleiche Ausgabe, bei der die Testdurchläufe erzeugt werden.
Verwenden von Schlüsselwortargumenten zum Abfangen von Python-Assert-Ausnahmen
Anders als beim Kontextmanager, wo wir nur die Ausnahme an assertRaises()
übergeben, übergeben wir auch den Funktionsaufruf und die Parameter der Funktion als Schlüsselwortargumente, um die Ausnahme hervorzurufen.
Syntax
assertRaises(exception, function, *args, **keywords)
Beispiel:
import unittest
class MyTestCase(unittest.TestCase):
def test_division_by_error(self):
import operator
self.assertRaises(ZeroDivisionError, operator.floordiv, 55, 0)
if __name__ == "__main__":
unittest.main()
Ausgabe:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Der obige Beispielcode verwendet assertRaises()
mit Schlüsselwortargumenten. Wir haben ihm die Ausnahme ZeroDivisionError
übergeben, die erwartet wurde, nachdem versucht wurde, eine Zahl durch Null zu teilen. Als zweites Argument haben wir die Operatorfunktion importiert, die mit der Operatorfunktion floordiv
verwendet wird. Parameterwerte sind hier die dritten Parameter; 55 durch 0 teilen.
Die letzte Anwendung von assert ist, wenn wir eine andere Ausnahme als die erwartete an assertRaises() übergeben. Stattdessen wird ein Fehler erzeugt.
Verwenden wir denselben Beispielcode, den wir gerade oben verwendet haben, und implementieren wir dies.
import unittest
class MyTestCase(unittest.TestCase):
def test_division_by_error(self):
import operator
self.assertRaises(TypeError, operator.floordiv, 55, 0)
if __name__ == "__main__":
unittest.main()
Ausgabe:
E
======================================================================
ERROR: test_division_by_error (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example
Articles\user.py", line 16, in test_division_by_error
self.assertRaises(TypeError, operator.floordiv, 55, 0)
File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 733, in assertRaises
return context.handle('assertRaises', args, kwargs)
File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 201, in handle
callable_obj(*args, **kwargs)
ZeroDivisionError: integer division or modulo by zero
----------------------------------------------------------------------
Ran 1 test in 0.031s
FAILED (errors=1)
Aus der Ausgabe wird ein Fehler-Traceback erzeugt. Wir erwarten eine ZeroDivisionError-Ausnahme, wenn wir eine Zahl durch Null teilen. Stattdessen übergeben wir eine TypeError-Ausnahme, die angewendet wird, wenn eine arithmetische Operation zwischen verschiedenen Datentypen ausgeführt wird, beispielsweise einer Zeichenkette und einer Ganzzahl.