Skippng Python unit tests if a dependency is missing (fixed)

I got some feedback on my previous post about skipping tests in python unittests pointing out my solution was flawed.  As Mu Mind pointed out, the denizens of stackoverflow pointed out the solution has a problem when run directly from python.  At first I didn’t realise how flawed; technically I had run my tests via python and nosetest regularly.  I just hadn’t realised that I’d never run the tests via python when I was missing the dependency.  If you do that you get this ugly error,

ERROR: test_openihm_gui_interface_db_mixin (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_openihm_gui_interface_db_mixin
Traceback (most recent call last):
  File "python2.7/unittest/loader.py", line 252, in _find_tests
    module = self._get_module_from_name(name)
  File "python2.7/unittest/loader.py", line 230, in _get_module_from_name
    __import__(name)
  File "tests/test_openihm_gui_interface_db_mixin.py", line 6, in 
    raise unittest.SkipTest("Need PyQt4 installed to do gui tests")
SkipTest: Need PyQt4 installed to do gui tests

It does tell you what the problem was clearly, but it really wasn’t the intention.  The idea was to silently skip the test.

From the answers and comments on the stackoverflow post I stitched together this ugly but hopefully working solution for whatever your unit test runner of choice is.

import unittest
try:
    import PyQt4
    # the rest of the imports


    class TestDataEntryMixin(unittest.TestCase):
        def test_somefeature(self):
            # actual tests go here.

except ImportError, e:
    if e.message.find('PyQt4') >= 0:
        class TestMissingDependency(unittest.TestCase):

            @unittest.skip('Missing dependency - ' + e.message)
            def test_fail():
                pass
    else:
        raise

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

I dislike the fact that I can’t hide away the logic at the top, but surrounding your whole test with the code works.  Then if the import fails we create a dummy test case that does a skip to indicate the problem. I’ve also tried to ensure that we only catch the exception we’re expecting, and pass through any we aren’t.

Now if you run the tests in verbose mode you’ll see this when there is a missing dependency.

test_fail (test_openihm_gui_interface_mixins.TestMissingDependency) ... skipped 'Missing dependency - No module named PyQt4'
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s