Reputation: 6095
In the Python unittest
framework, is there a way to pass a unit test if an exception wasn't raised, and fail with an AssertRaise otherwise?
Upvotes: 30
Views: 39944
Reputation: 1
I stumbled upon this question while looking for an answer to this obvious problem. Whilst the suggested solutions with try/except are fine, I found that I ended up with uncovered lines of code in coverage and that doesn't sit well with me. So I have come up with another solution, whilst not perfect, works for functions that only throw exceptions.
def check_raises(obj):
if obj.condition is True:
raise Exception('Condition is true')
In order to successfully test this function, I have resorted to using assertIsNone
. The below code covers both cases.
import unittest
class Object:
def __init__(self):
self.condition = None
class TestCheckRaises(unittest.TestCase):
def test_check_raises_exception(self):
obj = Object()
obj.condition = True
self.assertRaises(Exception, check_raises, obj)
def test_check_raises_no_exception(self):
obj = Object()
obj.condition = False
self.assertIsNone(check_raises(obj))
I am with the original poster that a assertNotRaises
would be nice, but failing that, assertIsNone
is perfectly acceptable for functions that do not return a value.
Upvotes: 0
Reputation: 63252
Simply call your functionality, e.g. do_something()
. If an unhandled exception gets raised, the test automatically fails! There is really no reason to do anything else. This is also the reason why assertDoesNotRaise()
does not exist.
Credit: comment by Sven
Upvotes: 5
Reputation: 1704
Many of the comments on this page treat errors and failures as equivalent, which they are not. The right solution in my opinion is to explicitly fail the test if the exception is raised. E.g.:
def test_does_not_error(self):
try:
code_under_test()
except ThatException:
self.fail("code_under_test raised ThatException")
Upvotes: 31
Reputation: 141770
If I understand your question correctly, you could do something like this:
def test_does_not_raise_on_valid_input(self):
raised = False
try:
do_something(42)
except:
raised = True
self.assertFalse(raised, 'Exception raised')
...assuming that you have a corresponding test that the correct Exception
gets raised on invalid input, of course:
def test_does_raise_on_invalid_input(self):
self.assertRaises(OutOfCheese, do_something, 43)
However, as pointed out in the comments, you need to consider what it is that you are actually testing. It's likely that a test like...
def test_what_is_42(self):
self.assertEquals(do_something(42), 'Meaning of life')
...is better because it tests the desired behaviour of the system and will fail if an exception is raised.
Upvotes: 36