"""
Loader that implements the ``load_tests`` protocol.
This plugin implements the ``load_tests`` protocol as detailed in the
documentation for :mod:`unittest2`.
See the `load_tests protocol`_ documentation for more information.
.. warning ::
Test suites using the ``load_tests`` protocol do not work correctly
with the :mod:`multiprocess` plugin as of nose2 04. This will be
fixed in a future release.
.. _load_tests protocol:
http://docs.python.org/library/unittest.html#load-tests-protocol
"""
import logging
from fnmatch import fnmatch
from nose2 import events, util
log = logging.getLogger(__name__)
[docs]class LoadTestsLoader(events.Plugin):
"""Loader plugin that implements load_tests."""
alwaysOn = True
configSection = "load_tests"
_loading = False
def registerInSubprocess(self, event):
event.pluginClasses.append(self.__class__)
[docs] def moduleLoadedSuite(self, event):
"""Run ``load_tests`` in a module.
May add to or filter tests loaded in module.
"""
module = event.module
load_tests = getattr(module, "load_tests", None)
if not load_tests:
return
try:
event.suite = load_tests(
event.loader, event.suite, self.session.testFilePattern
)
except Exception as exc:
log.exception("Failed to load tests from %s via load_tests", module)
suite = event.loader.suiteClass()
suite.addTest(event.loader.failedLoadTests(module.__name__, exc))
event.handled = True
return suite
[docs] def handleDir(self, event):
"""Run ``load_tests`` in packages.
If a package itself matches the test file pattern, run
``load_tests`` in its :file:`__init__.py`, and stop default test
discovery for that package.
"""
if self._loading:
return
if self._match(event.name, event.pattern) and util.ispackage(event.path):
name, _package_path = util.name_from_path(event.path)
module = util.module_from_name(name)
load_tests = getattr(module, "load_tests", None)
if not load_tests:
return
self._loading = True
try:
suite = event.loader.suiteClass()
try:
suite = load_tests(event.loader, suite, event.pattern)
except Exception as exc:
log.exception("Failed to load tests from %s via load_tests", module)
suite.addTest(event.loader.failedLoadTests(module.__name__, exc))
event.handled = True
return suite
finally:
self._loading = False
def _match(self, filename, pattern):
return fnmatch(filename, pattern)