case.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. """nose unittest.TestCase subclasses. It is not necessary to subclass these
  2. classes when writing tests; they are used internally by nose.loader.TestLoader
  3. to create test cases from test functions and methods in test classes.
  4. """
  5. import logging
  6. import sys
  7. import unittest
  8. from inspect import isfunction
  9. from nose.config import Config
  10. from nose.failure import Failure # for backwards compatibility
  11. from nose.util import resolve_name, test_address, try_run
  12. log = logging.getLogger(__name__)
  13. __all__ = ['Test']
  14. class Test(unittest.TestCase):
  15. """The universal test case wrapper.
  16. When a plugin sees a test, it will always see an instance of this
  17. class. To access the actual test case that will be run, access the
  18. test property of the nose.case.Test instance.
  19. """
  20. __test__ = False # do not collect
  21. def __init__(self, test, config=None, resultProxy=None):
  22. # sanity check
  23. if not callable(test):
  24. raise TypeError("nose.case.Test called with argument %r that "
  25. "is not callable. A callable is required."
  26. % test)
  27. self.test = test
  28. if config is None:
  29. config = Config()
  30. self.config = config
  31. self.tbinfo = None
  32. self.capturedOutput = None
  33. self.resultProxy = resultProxy
  34. self.plugins = config.plugins
  35. self.passed = None
  36. unittest.TestCase.__init__(self)
  37. def __call__(self, *arg, **kwarg):
  38. return self.run(*arg, **kwarg)
  39. def __str__(self):
  40. name = self.plugins.testName(self)
  41. if name is not None:
  42. return name
  43. return str(self.test)
  44. def __repr__(self):
  45. return "Test(%r)" % self.test
  46. def afterTest(self, result):
  47. """Called after test is complete (after result.stopTest)
  48. """
  49. try:
  50. afterTest = result.afterTest
  51. except AttributeError:
  52. pass
  53. else:
  54. afterTest(self.test)
  55. def beforeTest(self, result):
  56. """Called before test is run (before result.startTest)
  57. """
  58. try:
  59. beforeTest = result.beforeTest
  60. except AttributeError:
  61. pass
  62. else:
  63. beforeTest(self.test)
  64. def exc_info(self):
  65. """Extract exception info.
  66. """
  67. exc, exv, tb = sys.exc_info()
  68. return (exc, exv, tb)
  69. def id(self):
  70. """Get a short(er) description of the test
  71. """
  72. return self.test.id()
  73. def address(self):
  74. """Return a round-trip name for this test, a name that can be
  75. fed back as input to loadTestByName and (assuming the same
  76. plugin configuration) result in the loading of this test.
  77. """
  78. if hasattr(self.test, 'address'):
  79. return self.test.address()
  80. else:
  81. # not a nose case
  82. return test_address(self.test)
  83. def _context(self):
  84. try:
  85. return self.test.context
  86. except AttributeError:
  87. pass
  88. try:
  89. return self.test.__class__
  90. except AttributeError:
  91. pass
  92. try:
  93. return resolve_name(self.test.__module__)
  94. except AttributeError:
  95. pass
  96. return None
  97. context = property(_context, None, None,
  98. """Get the context object of this test (if any).""")
  99. def run(self, result):
  100. """Modified run for the test wrapper.
  101. From here we don't call result.startTest or stopTest or
  102. addSuccess. The wrapper calls addError/addFailure only if its
  103. own setup or teardown fails, or running the wrapped test fails
  104. (eg, if the wrapped "test" is not callable).
  105. Two additional methods are called, beforeTest and
  106. afterTest. These give plugins a chance to modify the wrapped
  107. test before it is called and do cleanup after it is
  108. called. They are called unconditionally.
  109. """
  110. if self.resultProxy:
  111. result = self.resultProxy(result, self)
  112. try:
  113. try:
  114. self.beforeTest(result)
  115. self.runTest(result)
  116. except KeyboardInterrupt:
  117. raise
  118. except:
  119. err = sys.exc_info()
  120. result.addError(self, err)
  121. finally:
  122. self.afterTest(result)
  123. def runTest(self, result):
  124. """Run the test. Plugins may alter the test by returning a
  125. value from prepareTestCase. The value must be callable and
  126. must accept one argument, the result instance.
  127. """
  128. test = self.test
  129. plug_test = self.config.plugins.prepareTestCase(self)
  130. if plug_test is not None:
  131. test = plug_test
  132. test(result)
  133. def shortDescription(self):
  134. desc = self.plugins.describeTest(self)
  135. if desc is not None:
  136. return desc
  137. # work around bug in unittest.TestCase.shortDescription
  138. # with multiline docstrings.
  139. test = self.test
  140. try:
  141. test._testMethodDoc = test._testMethodDoc.strip()# 2.5
  142. except AttributeError:
  143. try:
  144. # 2.4 and earlier
  145. test._TestCase__testMethodDoc = \
  146. test._TestCase__testMethodDoc.strip()
  147. except AttributeError:
  148. pass
  149. # 2.7 compat: shortDescription() always returns something
  150. # which is a change from 2.6 and below, and breaks the
  151. # testName plugin call.
  152. try:
  153. desc = self.test.shortDescription()
  154. except Exception:
  155. # this is probably caused by a problem in test.__str__() and is
  156. # only triggered by python 3.1's unittest!
  157. pass
  158. try:
  159. if desc == str(self.test):
  160. return
  161. except Exception:
  162. # If str() triggers an exception then ignore it.
  163. # see issue 422
  164. pass
  165. return desc
  166. class TestBase(unittest.TestCase):
  167. """Common functionality for FunctionTestCase and MethodTestCase.
  168. """
  169. __test__ = False # do not collect
  170. def id(self):
  171. return str(self)
  172. def runTest(self):
  173. self.test(*self.arg)
  174. def shortDescription(self):
  175. if hasattr(self.test, 'description'):
  176. return self.test.description
  177. func, arg = self._descriptors()
  178. doc = getattr(func, '__doc__', None)
  179. if not doc:
  180. doc = str(self)
  181. return doc.strip().split("\n")[0].strip()
  182. class FunctionTestCase(TestBase):
  183. """TestCase wrapper for test functions.
  184. Don't use this class directly; it is used internally in nose to
  185. create test cases for test functions.
  186. """
  187. __test__ = False # do not collect
  188. def __init__(self, test, setUp=None, tearDown=None, arg=tuple(),
  189. descriptor=None):
  190. """Initialize the MethodTestCase.
  191. Required argument:
  192. * test -- the test function to call.
  193. Optional arguments:
  194. * setUp -- function to run at setup.
  195. * tearDown -- function to run at teardown.
  196. * arg -- arguments to pass to the test function. This is to support
  197. generator functions that yield arguments.
  198. * descriptor -- the function, other than the test, that should be used
  199. to construct the test name. This is to support generator functions.
  200. """
  201. self.test = test
  202. self.setUpFunc = setUp
  203. self.tearDownFunc = tearDown
  204. self.arg = arg
  205. self.descriptor = descriptor
  206. TestBase.__init__(self)
  207. def address(self):
  208. """Return a round-trip name for this test, a name that can be
  209. fed back as input to loadTestByName and (assuming the same
  210. plugin configuration) result in the loading of this test.
  211. """
  212. if self.descriptor is not None:
  213. return test_address(self.descriptor)
  214. else:
  215. return test_address(self.test)
  216. def _context(self):
  217. return resolve_name(self.test.__module__)
  218. context = property(_context, None, None,
  219. """Get context (module) of this test""")
  220. def setUp(self):
  221. """Run any setup function attached to the test function
  222. """
  223. if self.setUpFunc:
  224. self.setUpFunc()
  225. else:
  226. names = ('setup', 'setUp', 'setUpFunc')
  227. try_run(self.test, names)
  228. def tearDown(self):
  229. """Run any teardown function attached to the test function
  230. """
  231. if self.tearDownFunc:
  232. self.tearDownFunc()
  233. else:
  234. names = ('teardown', 'tearDown', 'tearDownFunc')
  235. try_run(self.test, names)
  236. def __str__(self):
  237. func, arg = self._descriptors()
  238. if hasattr(func, 'compat_func_name'):
  239. name = func.compat_func_name
  240. else:
  241. name = func.__name__
  242. name = "%s.%s" % (func.__module__, name)
  243. if arg:
  244. name = "%s%s" % (name, arg)
  245. # FIXME need to include the full dir path to disambiguate
  246. # in cases where test module of the same name was seen in
  247. # another directory (old fromDirectory)
  248. return name
  249. __repr__ = __str__
  250. def _descriptors(self):
  251. """Get the descriptors of the test function: the function and
  252. arguments that will be used to construct the test name. In
  253. most cases, this is the function itself and no arguments. For
  254. tests generated by generator functions, the original
  255. (generator) function and args passed to the generated function
  256. are returned.
  257. """
  258. if self.descriptor:
  259. return self.descriptor, self.arg
  260. else:
  261. return self.test, self.arg
  262. class MethodTestCase(TestBase):
  263. """Test case wrapper for test methods.
  264. Don't use this class directly; it is used internally in nose to
  265. create test cases for test methods.
  266. """
  267. __test__ = False # do not collect
  268. def __init__(self, method, test=None, arg=tuple(), descriptor=None):
  269. """Initialize the MethodTestCase.
  270. Required argument:
  271. * method -- the method to call, may be bound or unbound. In either
  272. case, a new instance of the method's class will be instantiated to
  273. make the call. Note: In Python 3.x, if using an unbound method, you
  274. must wrap it using pyversion.unbound_method.
  275. Optional arguments:
  276. * test -- the test function to call. If this is passed, it will be
  277. called instead of getting a new bound method of the same name as the
  278. desired method from the test instance. This is to support generator
  279. methods that yield inline functions.
  280. * arg -- arguments to pass to the test function. This is to support
  281. generator methods that yield arguments.
  282. * descriptor -- the function, other than the test, that should be used
  283. to construct the test name. This is to support generator methods.
  284. """
  285. self.method = method
  286. self.test = test
  287. self.arg = arg
  288. self.descriptor = descriptor
  289. if isfunction(method):
  290. raise ValueError("Unbound methods must be wrapped using pyversion.unbound_method before passing to MethodTestCase")
  291. self.cls = method.im_class
  292. self.inst = self.cls()
  293. if self.test is None:
  294. method_name = self.method.__name__
  295. self.test = getattr(self.inst, method_name)
  296. TestBase.__init__(self)
  297. def __str__(self):
  298. func, arg = self._descriptors()
  299. if hasattr(func, 'compat_func_name'):
  300. name = func.compat_func_name
  301. else:
  302. name = func.__name__
  303. name = "%s.%s.%s" % (self.cls.__module__,
  304. self.cls.__name__,
  305. name)
  306. if arg:
  307. name = "%s%s" % (name, arg)
  308. return name
  309. __repr__ = __str__
  310. def address(self):
  311. """Return a round-trip name for this test, a name that can be
  312. fed back as input to loadTestByName and (assuming the same
  313. plugin configuration) result in the loading of this test.
  314. """
  315. if self.descriptor is not None:
  316. return test_address(self.descriptor)
  317. else:
  318. return test_address(self.method)
  319. def _context(self):
  320. return self.cls
  321. context = property(_context, None, None,
  322. """Get context (class) of this test""")
  323. def setUp(self):
  324. try_run(self.inst, ('setup', 'setUp'))
  325. def tearDown(self):
  326. try_run(self.inst, ('teardown', 'tearDown'))
  327. def _descriptors(self):
  328. """Get the descriptors of the test method: the method and
  329. arguments that will be used to construct the test name. In
  330. most cases, this is the method itself and no arguments. For
  331. tests generated by generator methods, the original
  332. (generator) method and args passed to the generated method
  333. or function are returned.
  334. """
  335. if self.descriptor:
  336. return self.descriptor, self.arg
  337. else:
  338. return self.method, self.arg