1230 Stimmen

Wie testet man, dass eine Python-Funktion eine Ausnahme auslöst?

Wie kann man einen Unittest schreiben, der nur dann fehlschlägt, wenn eine Funktion keine erwartete Ausnahme auslöst?

7voto

Hier gibt es eine Menge Antworten. Der Code zeigt, wie wir eine Exception erstellen können, wie wir diese Exception in unseren Methoden verwenden können und schließlich, wie Sie in einem Unit-Test überprüfen können, ob die richtigen Exceptions ausgelöst wurden.

import unittest

class DeviceException(Exception):
    def __init__(self, msg, code):
        self.msg = msg
        self.code = code
    def __str__(self):
        return repr("Error {}: {}".format(self.code, self.msg))

class MyDevice(object):
    def __init__(self):
        self.name = 'DefaultName'

    def setParameter(self, param, value):
        if isinstance(value, str):
            setattr(self, param , value)
        else:
            raise DeviceException('Incorrect type of argument passed. Name expects a string', 100001)

    def getParameter(self, param):
        return getattr(self, param)

class TestMyDevice(unittest.TestCase):

    def setUp(self):
        self.dev1 = MyDevice()

    def tearDown(self):
        del self.dev1

    def test_name(self):
        """ Test for valid input for name parameter """

        self.dev1.setParameter('name', 'MyDevice')
        name = self.dev1.getParameter('name')
        self.assertEqual(name, 'MyDevice')

    def test_invalid_name(self):
        """ Test to check if error is raised if invalid type of input is provided """

        self.assertRaises(DeviceException, self.dev1.setParameter, 'name', 1234)

    def test_exception_message(self):
        """ Test to check if correct exception message and code is raised when incorrect value is passed """

        with self.assertRaises(DeviceException) as cm:
            self.dev1.setParameter('name', 1234)
        self.assertEqual(cm.exception.msg, 'Incorrect type of argument passed. Name expects a string', 'mismatch in expected error message')
        self.assertEqual(cm.exception.code, 100001, 'mismatch in expected error code')

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

1 Stimmen

Der letzte Test test_exception_message war wirklich hilfreich. Ich musste die zurückgegebene Ausnahmemeldung erhalten. Vielen Dank

6voto

Daryl Spitzer Punkte 131841

Ich habe gerade entdeckt, dass die Musterbibliothek bietet eine assertRaisesWithMessage()-Methode (in ihrer Unterklasse unittest.TestCase), die nicht nur prüft, ob die erwartete Ausnahme ausgelöst wird, sondern auch, ob sie mit der erwarteten Meldung ausgelöst wird:

from testcase import TestCase

import mymod

class MyTestCase(TestCase):
    def test1(self):
        self.assertRaisesWithMessage(SomeCoolException,
                                     'expected message',
                                     mymod.myfunc)

2 Stimmen

Leider bietet es das nicht mehr. Aber die obige Antwort von @Art ( stackoverflow.com/a/3166985/1504046 ) ergibt das gleiche Ergebnis

5voto

Bruno Carvalho Punkte 157

Sie können assertRaises aus dem Unittest-Modul verwenden

import unittest

class TestClass():
  def raises_exception(self):
    raise Exception("test")

class MyTestCase(unittest.TestCase):
  def test_if_method_raises_correct_exception(self):
    test_class = TestClass()
    # note that you dont use () when passing the method to assertRaises
    self.assertRaises(Exception, test_class.raises_exception)

4voto

Sie können den Kontextmanager verwenden, um die fehlerhafte Funktion auszuführen und zu behaupten, dass sie die Ausnahme mit einer bestimmten Meldung auslöst, indem Sie assertRaisesMessage

with self.assertRaisesMessage(SomeException,'Some error message e.g 404 Not Found'):
    faulty_funtion()

3 Stimmen

assertRaisesMessage ist eine reine Django-Methode und keine native Methode der Python-Testcase-Klasse, wie in der Dokumentation angegeben aquí Bitte bearbeiten Sie Ihre Antwort, um dies zu klären.

2voto

Stephan Schielke Punkte 2586

Für await/async aiounittest gibt es ein etwas anderes Muster:

https://aiounittest.readthedocs.io/en/latest/asynctestcase.html#aiounittest.AsyncTestCase

async def test_await_async_fail(self):
    with self.assertRaises(Exception) as e:
        await async_one()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X