Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show the error messages caught by assertRaises() in unittest in Python2.7?

In order to make sure that the error messages from my module are informative, I would like to see all the error messages caught by assertRaises(). Today I do it for each assertRaises(), but as there are lots of them in the test code it gets very tedious.

How can I print the error messages for all the assertRaises()? I have studied the documentation on http://docs.python.org/library/unittest.html without figuring out how to solve it. Can I somehow monkeypatch the assertRaises() method? I prefer not to change all the assertRaises() lines in the test code, as I most often use the test code the standard way.

I guess this question is related to Python unittest: how do I test the argument in an Exceptions?

This is how I do it today. For example:

#!/usr/bin/env python  def fail():     raise ValueError('Misspellled errrorr messageee') 

And the test code:

#!/usr/bin/env python import unittest import failure     class TestFailureModule(unittest.TestCase):      def testFail(self):         self.assertRaises(ValueError, failure.fail)  if __name__ == '__main__':     unittest.main()   

To check the error message, I simply change the error type in the assertRaises() to for example IOError. Then I can see the error message:

 E ====================================================================== ERROR: testFail (__main__.TestFailureModule) ---------------------------------------------------------------------- Traceback (most recent call last):  File "test_failure.py", line 8, in testFail    self.assertRaises(IOError, failure.fail)   File "/usr/lib/python2.7/unittest/case.py", line 471, in assertRaises     callableObj(*args, **kwargs)  File "/home/jonas/Skrivbord/failure.py", line 4, in fail     raise ValueError('Misspellled errrorr messageee') ValueError: Misspellled errrorr messageee  ---------------------------------------------------------------------- Ran 1 test in 0.001s  FAILED (errors=1) 

Any suggestions? /Jonas

EDIT:

With the hints from Robert Rossney I managed to solve the problem. It is not mainly intended for spelling errors, but for making sure that the error messages are really meaningful for the user of the module. The normal functionality of unittest (this is how I use it most of the time) is achieved by setting SHOW_ERROR_MESSAGES = False.

I simply override the assertRaises() method, as seen below. It works like charm!

SHOW_ERROR_MESSAGES = True  class NonexistantError(Exception):     pass  class ExtendedTestCase(unittest.TestCase):     def assertRaises(self, excClass, callableObj, *args, **kwargs):         if SHOW_ERROR_MESSAGES:             excClass = NonexistantError         try:             unittest.TestCase.assertRaises(self, excClass, callableObj, *args, **kwargs)         except:             print '\n    ' + repr(sys.exc_info()[1])  

A fraction of the resulting output:

testNotIntegerInput (__main__.TestCheckRegisteraddress) ...      TypeError('The registeraddress must be an integer. Given: 1.0',)      TypeError("The registeraddress must be an integer. Given: '1'",)      TypeError('The registeraddress must be an integer. Given: [1]',)      TypeError('The registeraddress must be an integer. Given: None',) ok testCorrectNumberOfBytes (__main__.TestCheckResponseNumberOfBytes) ... ok testInconsistentLimits (__main__.TestCheckNumerical) ...      ValueError('The maxvalue must not be smaller than minvalue. Given: 45 and 47, respectively.',)      ValueError('The maxvalue must not be smaller than minvalue. Given: 45.0 and 47.0, respectively.',) ok testWrongValues (__main__.TestCheckRegisteraddress) ...      ValueError('The registeraddress is too small: -1, but minimum value is 0.',)      ValueError('The registeraddress is too large: 65536, but maximum value is 65535.',) ok testTooShortString (__main__.TestCheckResponseWriteData) ...      ValueError("The payload is too short: 2, but minimum value is 4. Given: '\\x00X'",)      ValueError("The payload is too short: 0, but minimum value is 4. Given: ''",)      ValueError("The writedata is too short: 1, but minimum value is 2. Given: 'X'",)      ValueError("The writedata is too short: 0, but minimum value is 2. Given: ''",) ok testKnownValues (__main__.TestCreateBitPattern) ... ok testNotIntegerInput (__main__.TestCheckSlaveaddress) ...      TypeError('The slaveaddress must be an integer. Given: 1.0',)      TypeError("The slaveaddress must be an integer. Given: '1'",)      TypeError('The slaveaddress must be an integer. Given: [1]',)      TypeError('The slaveaddress must be an integer. Given: None',) ok 
like image 348
jonasberg Avatar asked Dec 29 '11 19:12

jonasberg


People also ask

How do I print an exception message in Python?

To catch and print an exception that occurred in a code snippet, wrap it in an indented try block, followed by the command "except Exception as e" that catches the exception and saves its error message in string variable e . You can now print the error message with "print(e)" or use it for further processing.

What does Unittest main () do?

Internally, unittest. main() is using a few tricks to figure out the name of the module (source file) that contains the call to main() . It then imports this modules, examines it, gets a list of all classes and functions which could be tests (according the configuration) and then creates a test case for each of them.

How do you assert exceptions in Python?

There are two ways you can use assertRaises: using keyword arguments. Just pass the exception, the callable function and the parameters of the callable function as keyword arguments that will elicit the exception. Make a function call that should raise the exception with a context.


1 Answers

I once preferred the most excellent answer given above by @Robert Rossney. Nowadays, I prefer to use assertRaises as a context manager (a new capability in unittest2) like so:

with self.assertRaises(TypeError) as cm:     failure.fail() self.assertEqual(     'The registeraddress must be an integer. Given: 1.0',     str(cm.exception) ) 
like image 149
mkelley33 Avatar answered Sep 30 '22 06:09

mkelley33