The Python Oracle

How do you test that a Python function throws an exception?

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Sunrise at the Stream

--

Chapters
00:00 How Do You Test That A Python Function Throws An Exception?
00:10 Accepted Answer Score 24
00:37 Accepted Answer Score 1013
00:51 Answer 3 Score 700
01:23 Answer 4 Score 531
01:43 Answer 5 Score 175
03:43 Answer 6 Score 74
04:08 Thank you

--

Full question
https://stackoverflow.com/questions/1295...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #unittesting #exception

#avk47



ACCEPTED ANSWER

Score 1014


Use TestCase.assertRaises from the unittest module, for example:

import mymod

class MyTestCase(unittest.TestCase):
    def test1(self):
        self.assertRaises(SomeCoolException, mymod.myfunc)



ANSWER 2

Score 701


Since Python 2.7 you can use context manager to get ahold of the actual Exception object thrown:

import unittest

def broken_function():
    raise Exception('This is broken')

class MyTestCase(unittest.TestCase):
    def test(self):
        with self.assertRaises(Exception) as context:
            broken_function()

        self.assertTrue('This is broken' in context.exception)

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

assertRaises


In Python 3.5, you have to wrap context.exception in str, otherwise you'll get a TypeError

self.assertTrue('This is broken' in str(context.exception))



ANSWER 3

Score 532


The code in my previous answer can be simplified to:

def test_afunction_throws_exception(self):
    self.assertRaises(ExpectedException, afunction)

And if a function takes arguments, just pass them into assertRaises like this:

def test_afunction_throws_exception(self):
    self.assertRaises(ExpectedException, afunction, arg1, arg2)



ANSWER 4

Score 74


Your code should follow this pattern (this is a unittest module style test):

def test_afunction_throws_exception(self):
    try:
        afunction()
    except ExpectedException:
        pass
    except Exception:
       self.fail('unexpected exception raised')
    else:
       self.fail('ExpectedException not raised')

On Python < 2.7 this construct is useful for checking for specific values in the expected exception. The unittest function assertRaises only checks if an exception was raised.