4

Let's say I have a method that looks like this:

def my_function(arg1, arg2):
    if arg1:
        raise RuntimeError('error message A')
    else:
        raise RuntimeError('error message B')

Using python's builtin unittets library, is there any way to tell WHICH RuntimeError was raised? I have been doing:

import unittest
from myfile import my_function


class MyTestCase(unittest.TestCase):
    def test_my_function(self):
        self.assertRaises(RuntimeError, my_function, arg1, arg2)

But this only asserts that a RuntimeError was encountered. I want to be able to tell WHICH RuntimeError was encountered. Checking the actual error message is the only way I think this could be accomplished but I can't seem to find any assert method that also tries to assert the error message

Rosey
  • 739
  • 1
  • 12
  • 27

2 Answers2

3

unittest users:

In this case, it is better to use assertRaisesRegex.

Like assertRaises() but also tests that regex matches on the string representation of the raised exception. regex may be a regular expression object or a string containing a regular expression suitable for use by re.search().

So, you could use:

self.assertRaisesRegex(RuntimeError, "^error message A$", my_function, arg1, arg2)

pytest users:

Install my plugin pytest-raisin. Then you can assert using matching exception instances:

with pytest.raises(RuntimeError("error message A")):
    my_function(arg1, arg2)
wim
  • 338,267
  • 99
  • 616
  • 750
3

You can use assertRaises as a context manager and assert that string value of the exception object is as expected:

def my_function():
    raise RuntimeError('hello')

class MyTestCase(unittest.TestCase):
    def test_my_function(self):
        with self.assertRaises(RuntimeError) as cm:
            my_function()
        self.assertEqual(str(cm.exception), 'hello')

Demo: http://ideone.com/7J0HOR

blhsing
  • 91,368
  • 6
  • 71
  • 106
  • –1 Your code will not work, since the assertion on the exception string is unreachable – wim Sep 24 '19 at 18:23
  • Indeed. Fixed then. – blhsing Sep 24 '19 at 18:24
  • The edited code works. I accepted the other answer though since assertRaisesRegex syntax is much nicer – Rosey Sep 24 '19 at 18:33
  • @Rosey Indeed, although keep in mind that the `assertRaisesRegex` method is only available in Python 3, so if your project ever needs to support Python 2 you would have to settle with this more verbose approach. – blhsing Sep 24 '19 at 18:35
  • @blhsing incorrect, it's available in Python 2 but it's called `assertRaisesRegexp`. – wim Sep 24 '19 at 18:38
  • @wim Ah thanks I stand corrected. Not sure how I never noticed this method when I read through the documentation of `unittest` back then. – blhsing Sep 24 '19 at 18:40