From 94929992d67600ad88d90e2ba38f33baf1212350 Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Wed, 22 Jul 2015 16:12:18 +0100 Subject: [PATCH] Get rid of testtools so we can have sane reporting testtools turns exceptions into _StringExceptions for unknown reasons so let's get rid of that. Then, in gabbi.report lets override exc_info_to_string so we just don't do that. We want the actual exception information (which is a tuple of type, exception, tb). This gets us two things: * one less dependency * the ability for @FND to dig at the exception info as he likes, which is left as an exercise to him for a followup patch --- gabbi/case.py | 18 ++++++++++++++---- gabbi/reporter.py | 24 +++++++++++++++++------- gabbi/tests/test_fixtures.py | 4 ++-- gabbi/tests/test_handlers.py | 2 -- gabbi/tests/test_replacers.py | 4 ++-- gabbi/tests/test_utils.py | 4 ++-- requirements.txt | 1 - 7 files changed, 37 insertions(+), 20 deletions(-) diff --git a/gabbi/case.py b/gabbi/case.py index ec0c439..f965ead 100644 --- a/gabbi/case.py +++ b/gabbi/case.py @@ -26,11 +26,12 @@ import os import re import sys import time +import unittest +from unittest import case import jsonpath_rw import six from six.moves.urllib import parse as urlparse -from testtools import testcase import wsgi_intercept from gabbi import utils @@ -71,14 +72,18 @@ def potentialFailure(func): try: func(self) except Exception: - raise testcase._ExpectedFailure(sys.exc_info()) - raise testcase._UnexpectedSuccess + if hasattr(case, '_ExpectedFailure'): + raise case._ExpectedFailure(sys.exc_info()) + else: + self._addExpectedFailure(self.result, sys.exc_info()) + else: + raise case._UnexpectedSuccess else: func(self) return wrapper -class HTTPTestCase(testcase.TestCase): +class HTTPTestCase(unittest.TestCase): """Encapsulate a single HTTP request as a TestCase. If the test is a member of a sequence of requests, ensure that prior @@ -100,6 +105,11 @@ class HTTPTestCase(testcase.TestCase): super(HTTPTestCase, self).tearDown() self.has_run = True + def run(self, result=None): + """Store the current result handler on this test.""" + self.result = result + super(HTTPTestCase, self).run(result) + @potentialFailure def test_request(self): """Run this request if it has not yet run. diff --git a/gabbi/reporter.py b/gabbi/reporter.py index 9776b80..ad8c2b4 100644 --- a/gabbi/reporter.py +++ b/gabbi/reporter.py @@ -72,16 +72,26 @@ class ConciseTestResult(TextTestResult): desc = test.test_data.get('desc', None) return ': '.join((name, desc)) if desc else name + def _exc_info_to_string(self, err, test): + """Override exception to string handling + + The default does too much. We don't want doctoring. We want + information! + """ + return err + def printErrorList(self, flavor, errors): for test, err in errors: self.stream.writeln('%s: %s' % (flavor, self.getDescription(test))) - # extract details from traceback - # XXX: fugly workaround, for lack of a better solution - details = str(err) - details = details.strip().splitlines()[-1] # traceback's last line - if ':' in details: - details = details.split(':', 1)[1] # discard exception name - self.stream.writeln('\t%s' % details.strip()) + self.stream.writeln('%s:%s:%s' % (err[0], err[1][0][:70], err[2])) +# The rest is left as an exercise for FND +# details = err.strip().splitlines()[-1] # traceback's last line +# if ':' in details: +# details = details.split(':', 1)[1] # discard exception name +# if True: # some kind of flag here? +# self.stream.writeln('\t%s' % details[:70].strip()) +# else: +# self.stream.writeln('%s' % err) class ConciseTestRunner(TextTestRunner): diff --git a/gabbi/tests/test_fixtures.py b/gabbi/tests/test_fixtures.py index dbf1edf..19a8747 100644 --- a/gabbi/tests/test_fixtures.py +++ b/gabbi/tests/test_fixtures.py @@ -14,7 +14,7 @@ """ import mock -import testtools +import unittest from gabbi import fixture @@ -34,7 +34,7 @@ class FakeFixture(fixture.GabbiFixture): self.mock.stop() -class FixtureTest(testtools.TestCase): +class FixtureTest(unittest.TestCase): def setUp(self): super(FixtureTest, self).setUp() diff --git a/gabbi/tests/test_handlers.py b/gabbi/tests/test_handlers.py index 548ae20..18ce8b3 100644 --- a/gabbi/tests/test_handlers.py +++ b/gabbi/tests/test_handlers.py @@ -13,7 +13,6 @@ """Test response handlers. """ -from testtools import matchers import unittest from gabbi import case @@ -120,7 +119,6 @@ class HandlersTest(unittest.TestCase): self.test.response = {'content-type': 'application/json'} with self.assertRaises(AssertionError) as failure: self._assert_handler(handler) - self.assertIsInstance(failure.exception, matchers.MismatchError) self.assertIn("Expect header content-type with value text/plain," " got application/json", str(failure.exception)) diff --git a/gabbi/tests/test_replacers.py b/gabbi/tests/test_replacers.py index 752fe1d..9df0369 100644 --- a/gabbi/tests/test_replacers.py +++ b/gabbi/tests/test_replacers.py @@ -15,12 +15,12 @@ import os -import testtools +import unittest from gabbi import case -class EnvironReplaceTest(testtools.TestCase): +class EnvironReplaceTest(unittest.TestCase): def test_environ_boolean(self): """Environment variables are always strings diff --git a/gabbi/tests/test_utils.py b/gabbi/tests/test_utils.py index 084caab..b281109 100644 --- a/gabbi/tests/test_utils.py +++ b/gabbi/tests/test_utils.py @@ -13,12 +13,12 @@ """Test functions from the utils module. """ -import testtools +import unittest from gabbi import utils -class UtilsTest(testtools.TestCase): +class UtilsTest(unittest.TestCase): BINARY_TYPES = [ 'image/png', diff --git a/requirements.txt b/requirements.txt index 9513a19..ef398e2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ pbr six -testtools PyYAML httplib2 jsonpath-rw