Source code for nose2.plugins.loader.testcases

"""
Load tests from :class:`unittest.TestCase` subclasses.

This plugin implements :func:`loadTestsFromName` and
:func:`loadTestsFromModule` to load tests from
:class:`unittest.TestCase` subclasses found in modules or named on the
command line.


"""
# Adapted from unittest2/loader.py from the unittest2 plugins branch.
# This module contains some code copied from unittest2/loader.py and other
# code developed in reference to that module and others within unittest2.
# unittest2 is Copyright (c) 2001-2010 Python Software Foundation; All
# Rights Reserved. See: http://docs.python.org/license.html
import sys
import logging
import unittest

from nose2 import events, util


__unittest = True


log = logging.getLogger(__name__)


[docs]class TestCaseLoader(events.Plugin): """Loader plugin that loads from test cases""" alwaysOn = True configSection = 'testcases' def registerInSubprocess(self, event): event.pluginClasses.append(self.__class__)
[docs] def loadTestsFromModule(self, event): """Load tests in :class:`unittest.TestCase` subclasses""" seen = set() module = event.module for name in dir(module): obj = getattr(module, name) if id(obj) in seen: continue seen.add(id(obj)) if isinstance(obj, type) and issubclass(obj, unittest.TestCase): event.extraTests.append( self._loadTestsFromTestCase(event, obj))
[docs] def loadTestsFromName(self, event): """Load tests from event.name if it names a test case/method""" name = event.name module = event.module log.debug("load %s from %s", name, module) try: result = util.test_from_name(name, module) except (AttributeError, ImportError): event.handled = True return event.loader.failedLoadTests(name, sys.exc_info()) if result is None: return parent, obj, name, index = result if isinstance(obj, type) and issubclass(obj, unittest.TestCase): # name is a test case class event.extraTests.append(self._loadTestsFromTestCase(event, obj)) elif (isinstance(parent, type) and issubclass(parent, unittest.TestCase) and not util.isgenerator(obj) and not hasattr(obj, 'paramList')): # name is a single test method event.extraTests.append(parent(obj.__name__))
def _loadTestsFromTestCase(self, event, testCaseClass): evt = events.LoadFromTestCaseEvent(event.loader, testCaseClass) result = self.session.hooks.loadTestsFromTestCase(evt) if evt.handled: loaded_suite = result or event.loader.suiteClass() else: names = self._getTestCaseNames(event, testCaseClass) if not names and hasattr(testCaseClass, 'runTest'): names = ['runTest'] # FIXME return failure test case if name not in testcase class loaded_suite = event.loader.suiteClass(map(testCaseClass, names)) if evt.extraTests: loaded_suite.addTests(evt.extraTests) return loaded_suite def _getTestCaseNames(self, event, testCaseClass): excluded = set() def isTestMethod(attrname, testCaseClass=testCaseClass, excluded=excluded): prefix = evt.testMethodPrefix or self.session.testMethodPrefix return ( attrname.startswith(prefix) and hasattr(getattr(testCaseClass, attrname), '__call__') and attrname not in excluded ) evt = events.GetTestCaseNamesEvent( event.loader, testCaseClass, isTestMethod) result = self.session.hooks.getTestCaseNames(evt) if evt.handled: test_names = result or [] else: excluded.update(evt.excludedNames) test_names = [entry for entry in dir(testCaseClass) if isTestMethod(entry)] if evt.extraNames: test_names.extend(evt.extraNames) sortkey = getattr( testCaseClass, 'sortTestMethodsUsing', event.loader.sortTestMethodsUsing) if sortkey: test_names.sort( key=sortkey) return test_names