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'