pythonunit-testingnoseunittest2

How to do an "early return" of an import under Nose?


I'm curating a large number of unit tests for a large Python project. We use nose to do our test discovery and execution. I have some test files that really shouldn't be run in certain conditions. For instance, maybe I have a test module that should never be run on Windows (only on Mac and Linux).

Here are some solutions I have used:

  1. Mark test methods or classes with conditions using Nose's excellent attrib plugin.
  2. Use unittest.skipIf() on test methods or classes
  3. Use nose's pattern exclusions to skip files with windows in the name, for instance.

My complaint about 1 & 2 is that these force me to import the module, which is at least a waste of time and could possibly cause errors if there are platform dependent imports. I don't like #3 because I feel like it is brittle, and not easily apparent when reading the test case that it will be skipped. All three seem to depend excessively on the interaction between the test and the test runner, I'd like something that is just in the test.

I would like to do something like the following at the top of the test module:

"""This module should not be run on Windows"""
import platform
if platform.system() == 'Windows':
    <stop reading this module.  nothing to see here>

# do the tests.

How can I tell Python or Nose to stop reading the module, but that there is no error? I guess I am looking for the import equivalent of an early return.


Solution

  • Under Nose and unittest, the SkipTest exception is treated specially - it's not a failure. Thus, the following code will stop execution, and no error will be reported to the unittest runner:

    import unittest
    import platform
    if platform.system() == 'Windows':
      raise unittest.case.SkipTest("The rest of this code will not be run on Windows.")