Prettifying Python’s unittest output (and making it more informative)

Yeah, I still write code. I just can’t publicly talk about it. Yet.

Recently, I have been writing unit tests that involve passing source code through GCC and then running the resulting compiled binary. Given that PyObjC already does this for the unit tests of ffi, I started my test harness by ripping off that one.

My tests actually look for very specific warnings and failures from GCC. So, I augmented the script slightly to allow me to embed “expect this warning/error” into the source to be compiled.

When such a test fails, it is terribly useful to actually see the command line that was invoked. Unfortunately, it doesn’t appear that Python’s unittest TestCase class has a hook for composing the failure details. But it does have a hook for easily setting the class of the exception that will be raised. From there, it is easy enough to pass a reference back to the TestCase into the various assert methods to allow a custom exception class to provide more info.

Don’t bother trying to parse that paragraph, just read the code:

class TestCaseAssertionError (AssertionError):
    def __str__(self):
        if len(self.args) is 2:
            msg, testCase = self.args
            return "\\n\\nCompiled using:\\n\\t%s\\n\\n------ Details ------\\n%s\\n------ End Details ------" % (testCase.commandline, str(msg))
            return str(self.args)

class DgTestCase (unittest.TestCase):
    failureException = TestCaseAssertionError
    def __init__(self, filename):
        self.filename = filename
        self.commandline = None

    ... at some point, the command line is composed and self.commandline is set ....

    ... then, in a test case ....
    self.assertNotEqual(actual.strip().find(expected.strip()), -1,
    ("Expected to find:\\n\\t%s\\nNot found in:\\n\\t%s" % (expected.strip(), actual.strip()), self))

Easy enough. Now, when a compiler failure occurs, I can easily copy/paste the command line to see the full output or deduce the issue further. Though the above is completely specific to my needs it would be easy to generalize.

Leave a Reply

Line and paragraph breaks automatic.
XHTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>