Silence exceptions that do not result in test failure in python unittest

943 Views Asked by At

I am writing unit tests for a python program using the unittest framework. One of the functions of the program is connecting to an external REST API using the requests library. If there is a connection error or timeout, I would like the function to retry up to 3 times before failing. As such I have written a test which uses a mock (actually httpretty) to replace the external API and raises requests.ConnectionError twice before returning something.

class APITests(unittest.TestCase):

    def mock_response(self, uri, body='OK', method=httpretty.GET,
                      status_code=200, error=None,
                      error_repeats=None):
        """
        Function to register HTTPretty response
        """
        responses = []

        if error:
            def callback(request, uri, headers):
                raise error

            if error_repeats:
                responses += [httpretty.Response(body=callback)]*error_repeats
                responses += [httpretty.Response(body=body,
                                                 status=status_code)]
            else:
                responses += [httpretty.Response(body=callback)]

        else:
            responses += [httpretty.Response(body=body, status=status_code)]

        httpretty.register_uri(method, uri, responses=responses)

    @httpretty.activate
    def test_get_connection_error_then_success_doesnt_raise(self):
        self.mock_response(
                'http://irrelevant.com',
                error=requests.ConnectionError,
                error_repeats=2
            )
        api._get('http://irrelevant.com')  

This works fine and the test passes when an exception is not raised no the third attempt but the two exceptions that are raised (intentionally) and caught and handled by the code are printed to the console, polluting the test output. Is there a clean way to stop this happening?

Further info

Here is the method(s) I am testing

def _get(self, url, retries=3):
    while retries > 0:
        try:
            r = requests.get(url)
            try:
                r.raise_for_status()
                return r
            except requests.HTTPError as e:
                self._handle_HTTP_error(e)
        except (requests.ConnectionError, requests.Timeout) as e:
            retries -= 1
            if not retries:
                self._handle_connection_error(e)

def _handle_connection_error(self, error):
    raise requests.ConnectionError('Could not connect to API')

The console output is:

Exception in thread Thread-23:
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/Users/lukecaldwell/Documents/Repos/other/AidTrends/venv/lib/python2.7/site-packages/httpretty/core.py", line 637, in fill_filekind
    headers
  File "/Users/lukecaldwell/Documents/Repos/other/AidTrends/aidtrends/tests/test_OECD.py", line 131, in callback
    raise error
ConnectionError
0

There are 0 best solutions below