0

I am new to Python. I wanted to test if my code threw an exception. I got the code from How do you test that a Python function throws an exception?

import mymod
import unittest

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

Now, I also want to display a message if the exception is not thrown. How do I do that? The Python documentation does not mention it clearly. I added the message after "compulsory_argument" and it failed.


I tried the first answer with modifications and got an exception. What is my mistake here?

import unittest

def sayHelloTo(name):
    print("Hello " + name)

class MyTestCase(unittest.TestCase):
    def test1(self):
        person = "John"
        with self.assertRaises(Exception, "My insightful message"):
            sayHelloTo(person)

Error:

Error
Traceback (most recent call last):
  File "C:\tests\tester.py", line 9, in test1
    with self.assertRaises(Exception, "My insightful message"):
AttributeError: __exit__
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Erran Morad
  • 4,563
  • 10
  • 43
  • 72
  • A `raise` will through an exception, and a `print` will print a message. Combine these two to get the behaviour you want. – boardrider Oct 07 '16 at 18:01

2 Answers2

5

As of Python 3.3, assertRaises can be used as a context manager with a message:

import unittest

def sayHelloTo(name):
    print("Hello " + name)

class MyTestCase(unittest.TestCase):
    def test1(self):
        person = "John"
        with self.assertRaises(Exception, msg="My insightful message"):
            sayHelloTo(person)

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

It results in

Hello John
F
======================================================================
FAIL: test1 (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "r.py", line 10, in test1
    sayHelloTo(person)
AssertionError: Exception not raised : My insightful message

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • I tried your code and got an error. Please see the edits I am going to add in the question body. – Erran Morad Oct 07 '16 at 15:11
  • @tdelany- Thanks. It works now. Can you please tell me why it started working after you passed the message like this `msg="My insightful message"` ? What prompted you to think in that direction ? – Erran Morad Oct 08 '16 at 00:38
  • The docs mentioned a "msg argument" but I didn't read it close enough to realize it was a keyword argument, not a positional one. Another user, unutbu, pointed out my mistake and that got it working. – tdelaney Oct 08 '16 at 15:27
  • This doesn't work when another exception is raised during the test. Any idea how to still post the "insightful" message even when a different exception is raised? – ddejohn Mar 02 '21 at 02:44
1

Now, I also want to display a message if the exception is not thrown. How do I do that ?

The general philosophy of unittest is for the tests to be silent when they succeed and only become verbose when they fail. Accordingly, the API provides a "msg" keyword argument for the unsuccessful case but does not offer an alternative for the successful case.

That said, another part of the philosophy works in your favor. In general, test cases internally raise an exception when a testcase fails. That means that if you want to display a message when there is a success, you just add another statement after the test:

with self.assertRaises(TypeError, msg='Oh no, I did not get a TypeError')
     somecode()
logging.info('Yippee, we got a TypeError!')  # Runs after a successful test
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485