selector.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. """
  2. Test Selection
  3. --------------
  4. Test selection is handled by a Selector. The test loader calls the
  5. appropriate selector method for each object it encounters that it
  6. thinks may be a test.
  7. """
  8. import logging
  9. import os
  10. import unittest
  11. from nose.config import Config
  12. from nose.util import split_test_name, src, getfilename, getpackage, ispackage, is_executable
  13. log = logging.getLogger(__name__)
  14. __all__ = ['Selector', 'defaultSelector', 'TestAddress']
  15. # for efficiency and easier mocking
  16. op_join = os.path.join
  17. op_basename = os.path.basename
  18. op_exists = os.path.exists
  19. op_splitext = os.path.splitext
  20. op_isabs = os.path.isabs
  21. op_abspath = os.path.abspath
  22. class Selector(object):
  23. """Core test selector. Examines test candidates and determines whether,
  24. given the specified configuration, the test candidate should be selected
  25. as a test.
  26. """
  27. def __init__(self, config):
  28. if config is None:
  29. config = Config()
  30. self.configure(config)
  31. def configure(self, config):
  32. self.config = config
  33. self.exclude = config.exclude
  34. self.ignoreFiles = config.ignoreFiles
  35. self.include = config.include
  36. self.plugins = config.plugins
  37. self.match = config.testMatch
  38. def matches(self, name):
  39. """Does the name match my requirements?
  40. To match, a name must match config.testMatch OR config.include
  41. and it must not match config.exclude
  42. """
  43. return ((self.match.search(name)
  44. or (self.include and
  45. filter(None,
  46. [inc.search(name) for inc in self.include])))
  47. and ((not self.exclude)
  48. or not filter(None,
  49. [exc.search(name) for exc in self.exclude])
  50. ))
  51. def wantClass(self, cls):
  52. """Is the class a wanted test class?
  53. A class must be a unittest.TestCase subclass, or match test name
  54. requirements. Classes that start with _ are always excluded.
  55. """
  56. declared = getattr(cls, '__test__', None)
  57. if declared is not None:
  58. wanted = declared
  59. else:
  60. wanted = (not cls.__name__.startswith('_')
  61. and (issubclass(cls, unittest.TestCase)
  62. or self.matches(cls.__name__)))
  63. plug_wants = self.plugins.wantClass(cls)
  64. if plug_wants is not None:
  65. log.debug("Plugin setting selection of %s to %s", cls, plug_wants)
  66. wanted = plug_wants
  67. log.debug("wantClass %s? %s", cls, wanted)
  68. return wanted
  69. def wantDirectory(self, dirname):
  70. """Is the directory a wanted test directory?
  71. All package directories match, so long as they do not match exclude.
  72. All other directories must match test requirements.
  73. """
  74. tail = op_basename(dirname)
  75. if ispackage(dirname):
  76. wanted = (not self.exclude
  77. or not filter(None,
  78. [exc.search(tail) for exc in self.exclude]
  79. ))
  80. else:
  81. wanted = (self.matches(tail)
  82. or (self.config.srcDirs
  83. and tail in self.config.srcDirs))
  84. plug_wants = self.plugins.wantDirectory(dirname)
  85. if plug_wants is not None:
  86. log.debug("Plugin setting selection of %s to %s",
  87. dirname, plug_wants)
  88. wanted = plug_wants
  89. log.debug("wantDirectory %s? %s", dirname, wanted)
  90. return wanted
  91. def wantFile(self, file):
  92. """Is the file a wanted test file?
  93. The file must be a python source file and match testMatch or
  94. include, and not match exclude. Files that match ignore are *never*
  95. wanted, regardless of plugin, testMatch, include or exclude settings.
  96. """
  97. # never, ever load files that match anything in ignore
  98. # (.* _* and *setup*.py by default)
  99. base = op_basename(file)
  100. ignore_matches = [ ignore_this for ignore_this in self.ignoreFiles
  101. if ignore_this.search(base) ]
  102. if ignore_matches:
  103. log.debug('%s matches ignoreFiles pattern; skipped',
  104. base)
  105. return False
  106. if not self.config.includeExe and is_executable(file):
  107. log.info('%s is executable; skipped', file)
  108. return False
  109. dummy, ext = op_splitext(base)
  110. pysrc = ext == '.py'
  111. wanted = pysrc and self.matches(base)
  112. plug_wants = self.plugins.wantFile(file)
  113. if plug_wants is not None:
  114. log.debug("plugin setting want %s to %s", file, plug_wants)
  115. wanted = plug_wants
  116. log.debug("wantFile %s? %s", file, wanted)
  117. return wanted
  118. def wantFunction(self, function):
  119. """Is the function a test function?
  120. """
  121. try:
  122. if hasattr(function, 'compat_func_name'):
  123. funcname = function.compat_func_name
  124. else:
  125. funcname = function.__name__
  126. except AttributeError:
  127. # not a function
  128. return False
  129. declared = getattr(function, '__test__', None)
  130. if declared is not None:
  131. wanted = declared
  132. else:
  133. wanted = not funcname.startswith('_') and self.matches(funcname)
  134. plug_wants = self.plugins.wantFunction(function)
  135. if plug_wants is not None:
  136. wanted = plug_wants
  137. log.debug("wantFunction %s? %s", function, wanted)
  138. return wanted
  139. def wantMethod(self, method):
  140. """Is the method a test method?
  141. """
  142. try:
  143. method_name = method.__name__
  144. except AttributeError:
  145. # not a method
  146. return False
  147. if method_name.startswith('_'):
  148. # never collect 'private' methods
  149. return False
  150. declared = getattr(method, '__test__', None)
  151. if declared is not None:
  152. wanted = declared
  153. else:
  154. wanted = self.matches(method_name)
  155. plug_wants = self.plugins.wantMethod(method)
  156. if plug_wants is not None:
  157. wanted = plug_wants
  158. log.debug("wantMethod %s? %s", method, wanted)
  159. return wanted
  160. def wantModule(self, module):
  161. """Is the module a test module?
  162. The tail of the module name must match test requirements. One exception:
  163. we always want __main__.
  164. """
  165. declared = getattr(module, '__test__', None)
  166. if declared is not None:
  167. wanted = declared
  168. else:
  169. wanted = self.matches(module.__name__.split('.')[-1]) \
  170. or module.__name__ == '__main__'
  171. plug_wants = self.plugins.wantModule(module)
  172. if plug_wants is not None:
  173. wanted = plug_wants
  174. log.debug("wantModule %s? %s", module, wanted)
  175. return wanted
  176. defaultSelector = Selector
  177. class TestAddress(object):
  178. """A test address represents a user's request to run a particular
  179. test. The user may specify a filename or module (or neither),
  180. and/or a callable (a class, function, or method). The naming
  181. format for test addresses is:
  182. filename_or_module:callable
  183. Filenames that are not absolute will be made absolute relative to
  184. the working dir.
  185. The filename or module part will be considered a module name if it
  186. doesn't look like a file, that is, if it doesn't exist on the file
  187. system and it doesn't contain any directory separators and it
  188. doesn't end in .py.
  189. Callables may be a class name, function name, method name, or
  190. class.method specification.
  191. """
  192. def __init__(self, name, workingDir=None):
  193. if workingDir is None:
  194. workingDir = os.getcwd()
  195. self.name = name
  196. self.workingDir = workingDir
  197. self.filename, self.module, self.call = split_test_name(name)
  198. log.debug('Test name %s resolved to file %s, module %s, call %s',
  199. name, self.filename, self.module, self.call)
  200. if self.filename is None:
  201. if self.module is not None:
  202. self.filename = getfilename(self.module, self.workingDir)
  203. if self.filename:
  204. self.filename = src(self.filename)
  205. if not op_isabs(self.filename):
  206. self.filename = op_abspath(op_join(workingDir,
  207. self.filename))
  208. if self.module is None:
  209. self.module = getpackage(self.filename)
  210. log.debug(
  211. 'Final resolution of test name %s: file %s module %s call %s',
  212. name, self.filename, self.module, self.call)
  213. def totuple(self):
  214. return (self.filename, self.module, self.call)
  215. def __str__(self):
  216. return self.name
  217. def __repr__(self):
  218. return "%s: (%s, %s, %s)" % (self.name, self.filename,
  219. self.module, self.call)