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