| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2001-2007 Twisted Matrix Laboratories. | |
| 2 # See LICENSE for details. | |
| 3 | |
| 4 import gc | |
| 5 import StringIO, sys, types | |
| 6 | |
| 7 from twisted.trial import unittest, runner | |
| 8 from twisted.scripts import trial | |
| 9 from twisted.python import util | |
| 10 from twisted.python.compat import set | |
| 11 | |
| 12 from twisted.trial.test.test_loader import testNames | |
| 13 | |
| 14 pyunit = __import__('unittest') | |
| 15 | |
| 16 | |
| 17 def sibpath(filename): | |
| 18 """For finding files in twisted/trial/test""" | |
| 19 return util.sibpath(__file__, filename) | |
| 20 | |
| 21 | |
| 22 | |
| 23 class ForceGarbageCollection(unittest.TestCase): | |
| 24 """ | |
| 25 Tests for the --force-gc option. | |
| 26 """ | |
| 27 | |
| 28 def setUp(self): | |
| 29 self.config = trial.Options() | |
| 30 self.log = [] | |
| 31 self.patch(gc, 'collect', self.collect) | |
| 32 test = pyunit.FunctionTestCase(self.simpleTest) | |
| 33 self.test = runner.TestSuite([test, test]) | |
| 34 | |
| 35 | |
| 36 def simpleTest(self): | |
| 37 """ | |
| 38 A simple test method that records that it was run. | |
| 39 """ | |
| 40 self.log.append('test') | |
| 41 | |
| 42 | |
| 43 def collect(self): | |
| 44 """ | |
| 45 A replacement for gc.collect that logs calls to itself. | |
| 46 """ | |
| 47 self.log.append('collect') | |
| 48 | |
| 49 | |
| 50 def makeRunner(self): | |
| 51 """ | |
| 52 Return a L{runner.TrialRunner} object that is safe to use in tests. | |
| 53 """ | |
| 54 runner = trial._makeRunner(self.config) | |
| 55 runner.stream = StringIO.StringIO() | |
| 56 return runner | |
| 57 | |
| 58 | |
| 59 def test_forceGc(self): | |
| 60 """ | |
| 61 Passing the --force-gc option to the trial script forces the garbage | |
| 62 collector to run before and after each test. | |
| 63 """ | |
| 64 self.config['force-gc'] = True | |
| 65 self.config.postOptions() | |
| 66 runner = self.makeRunner() | |
| 67 runner.run(self.test) | |
| 68 self.assertEqual(self.log, ['collect', 'test', 'collect', | |
| 69 'collect', 'test', 'collect']) | |
| 70 | |
| 71 | |
| 72 def test_unforceGc(self): | |
| 73 """ | |
| 74 By default, no garbage collection is forced. | |
| 75 """ | |
| 76 self.config.postOptions() | |
| 77 runner = self.makeRunner() | |
| 78 runner.run(self.test) | |
| 79 self.assertEqual(self.log, ['test', 'test']) | |
| 80 | |
| 81 | |
| 82 | |
| 83 class TestSuiteUsed(unittest.TestCase): | |
| 84 """ | |
| 85 Check the category of tests suite used by the loader. | |
| 86 """ | |
| 87 | |
| 88 def setUp(self): | |
| 89 """ | |
| 90 Create a trial configuration object. | |
| 91 """ | |
| 92 self.config = trial.Options() | |
| 93 | |
| 94 | |
| 95 def test_defaultSuite(self): | |
| 96 """ | |
| 97 By default, the loader should use L{runner.DestructiveTestSuite} | |
| 98 """ | |
| 99 loader = trial._getLoader(self.config) | |
| 100 self.assertEquals(loader.suiteFactory, runner.DestructiveTestSuite) | |
| 101 | |
| 102 | |
| 103 def test_untilFailureSuite(self): | |
| 104 """ | |
| 105 The C{until-failure} configuration uses the L{runner.TestSuite} to keep | |
| 106 instances alive across runs. | |
| 107 """ | |
| 108 self.config['until-failure'] = True | |
| 109 loader = trial._getLoader(self.config) | |
| 110 self.assertEquals(loader.suiteFactory, runner.TestSuite) | |
| 111 | |
| 112 | |
| 113 | |
| 114 class TestModuleTest(unittest.TestCase): | |
| 115 def setUp(self): | |
| 116 self.config = trial.Options() | |
| 117 | |
| 118 def tearDown(self): | |
| 119 self.config = None | |
| 120 | |
| 121 def test_testNames(self): | |
| 122 """ | |
| 123 Check that the testNames helper method accurately collects the | |
| 124 names of tests in suite. | |
| 125 """ | |
| 126 self.assertEqual(testNames(self), [self.id()]) | |
| 127 | |
| 128 def assertSuitesEqual(self, test1, names): | |
| 129 loader = runner.TestLoader() | |
| 130 names1 = testNames(test1) | |
| 131 names2 = testNames(runner.TestSuite(map(loader.loadByName, names))) | |
| 132 names1.sort() | |
| 133 names2.sort() | |
| 134 self.assertEqual(names1, names2) | |
| 135 | |
| 136 def test_baseState(self): | |
| 137 self.failUnlessEqual(0, len(self.config['tests'])) | |
| 138 | |
| 139 def test_testmoduleOnModule(self): | |
| 140 """ | |
| 141 Check that --testmodule loads a suite which contains the tests | |
| 142 referred to in test-case-name inside its parameter. | |
| 143 """ | |
| 144 self.config.opt_testmodule(sibpath('moduletest.py')) | |
| 145 self.assertSuitesEqual(trial._getSuite(self.config), | |
| 146 ['twisted.trial.test.test_test_visitor']) | |
| 147 | |
| 148 def test_testmoduleTwice(self): | |
| 149 """ | |
| 150 When the same module is specified with two --testmodule flags, it | |
| 151 should only appear once in the suite. | |
| 152 """ | |
| 153 self.config.opt_testmodule(sibpath('moduletest.py')) | |
| 154 self.config.opt_testmodule(sibpath('moduletest.py')) | |
| 155 self.assertSuitesEqual(trial._getSuite(self.config), | |
| 156 ['twisted.trial.test.test_test_visitor']) | |
| 157 | |
| 158 def test_testmoduleOnSourceAndTarget(self): | |
| 159 """ | |
| 160 If --testmodule is specified twice, once for module A and once for | |
| 161 a module which refers to module A, then make sure module A is only | |
| 162 added once. | |
| 163 """ | |
| 164 self.config.opt_testmodule(sibpath('moduletest.py')) | |
| 165 self.config.opt_testmodule(sibpath('test_test_visitor.py')) | |
| 166 self.assertSuitesEqual(trial._getSuite(self.config), | |
| 167 ['twisted.trial.test.test_test_visitor']) | |
| 168 | |
| 169 def test_testmoduleOnSelfModule(self): | |
| 170 """ | |
| 171 When given a module that refers to *itself* in the test-case-name | |
| 172 variable, check that --testmodule only adds the tests once. | |
| 173 """ | |
| 174 self.config.opt_testmodule(sibpath('moduleself.py')) | |
| 175 self.assertSuitesEqual(trial._getSuite(self.config), | |
| 176 ['twisted.trial.test.moduleself']) | |
| 177 | |
| 178 def test_testmoduleOnScript(self): | |
| 179 """ | |
| 180 Check that --testmodule loads tests referred to in test-case-name | |
| 181 buffer variables. | |
| 182 """ | |
| 183 self.config.opt_testmodule(sibpath('scripttest.py')) | |
| 184 self.assertSuitesEqual(trial._getSuite(self.config), | |
| 185 ['twisted.trial.test.test_test_visitor', | |
| 186 'twisted.trial.test.test_class']) | |
| 187 | |
| 188 def test_testmoduleOnNonexistentFile(self): | |
| 189 """ | |
| 190 Check that --testmodule displays a meaningful error message when | |
| 191 passed a non-existent filename. | |
| 192 """ | |
| 193 buffy = StringIO.StringIO() | |
| 194 stderr, sys.stderr = sys.stderr, buffy | |
| 195 filename = 'test_thisbetternoteverexist.py' | |
| 196 try: | |
| 197 self.config.opt_testmodule(filename) | |
| 198 self.failUnlessEqual(0, len(self.config['tests'])) | |
| 199 self.failUnlessEqual("File %r doesn't exist\n" % (filename,), | |
| 200 buffy.getvalue()) | |
| 201 finally: | |
| 202 sys.stderr = stderr | |
| 203 | |
| 204 def test_testmoduleOnEmptyVars(self): | |
| 205 """ | |
| 206 Check that --testmodule adds no tests to the suite for modules | |
| 207 which lack test-case-name buffer variables. | |
| 208 """ | |
| 209 self.config.opt_testmodule(sibpath('novars.py')) | |
| 210 self.failUnlessEqual(0, len(self.config['tests'])) | |
| 211 | |
| 212 def test_testmoduleOnModuleName(self): | |
| 213 """ | |
| 214 Check that --testmodule does *not* support module names as arguments | |
| 215 and that it displays a meaningful error message. | |
| 216 """ | |
| 217 buffy = StringIO.StringIO() | |
| 218 stderr, sys.stderr = sys.stderr, buffy | |
| 219 moduleName = 'twisted.trial.test.test_script' | |
| 220 try: | |
| 221 self.config.opt_testmodule(moduleName) | |
| 222 self.failUnlessEqual(0, len(self.config['tests'])) | |
| 223 self.failUnlessEqual("File %r doesn't exist\n" % (moduleName,), | |
| 224 buffy.getvalue()) | |
| 225 finally: | |
| 226 sys.stderr = stderr | |
| 227 | |
| 228 def test_parseLocalVariable(self): | |
| 229 declaration = '-*- test-case-name: twisted.trial.test.test_tests -*-' | |
| 230 localVars = trial._parseLocalVariables(declaration) | |
| 231 self.failUnlessEqual({'test-case-name': | |
| 232 'twisted.trial.test.test_tests'}, | |
| 233 localVars) | |
| 234 | |
| 235 def test_trailingSemicolon(self): | |
| 236 declaration = '-*- test-case-name: twisted.trial.test.test_tests; -*-' | |
| 237 localVars = trial._parseLocalVariables(declaration) | |
| 238 self.failUnlessEqual({'test-case-name': | |
| 239 'twisted.trial.test.test_tests'}, | |
| 240 localVars) | |
| 241 | |
| 242 def test_parseLocalVariables(self): | |
| 243 declaration = ('-*- test-case-name: twisted.trial.test.test_tests; ' | |
| 244 'foo: bar -*-') | |
| 245 localVars = trial._parseLocalVariables(declaration) | |
| 246 self.failUnlessEqual({'test-case-name': | |
| 247 'twisted.trial.test.test_tests', | |
| 248 'foo': 'bar'}, | |
| 249 localVars) | |
| 250 | |
| 251 def test_surroundingGuff(self): | |
| 252 declaration = ('## -*- test-case-name: ' | |
| 253 'twisted.trial.test.test_tests -*- #') | |
| 254 localVars = trial._parseLocalVariables(declaration) | |
| 255 self.failUnlessEqual({'test-case-name': | |
| 256 'twisted.trial.test.test_tests'}, | |
| 257 localVars) | |
| 258 | |
| 259 def test_invalidLine(self): | |
| 260 self.failUnlessRaises(ValueError, trial._parseLocalVariables, | |
| 261 'foo') | |
| 262 | |
| 263 def test_invalidDeclaration(self): | |
| 264 self.failUnlessRaises(ValueError, trial._parseLocalVariables, | |
| 265 '-*- foo -*-') | |
| 266 self.failUnlessRaises(ValueError, trial._parseLocalVariables, | |
| 267 '-*- foo: bar; qux -*-') | |
| 268 self.failUnlessRaises(ValueError, trial._parseLocalVariables, | |
| 269 '-*- foo: bar: baz; qux: qax -*-') | |
| 270 | |
| 271 def test_variablesFromFile(self): | |
| 272 localVars = trial.loadLocalVariables(sibpath('moduletest.py')) | |
| 273 self.failUnlessEqual({'test-case-name': | |
| 274 'twisted.trial.test.test_test_visitor'}, | |
| 275 localVars) | |
| 276 | |
| 277 def test_noVariablesInFile(self): | |
| 278 localVars = trial.loadLocalVariables(sibpath('novars.py')) | |
| 279 self.failUnlessEqual({}, localVars) | |
| 280 | |
| 281 def test_variablesFromScript(self): | |
| 282 localVars = trial.loadLocalVariables(sibpath('scripttest.py')) | |
| 283 self.failUnlessEqual( | |
| 284 {'test-case-name': ('twisted.trial.test.test_test_visitor,' | |
| 285 'twisted.trial.test.test_class')}, | |
| 286 localVars) | |
| 287 | |
| 288 def test_getTestModules(self): | |
| 289 modules = trial.getTestModules(sibpath('moduletest.py')) | |
| 290 self.failUnlessEqual(modules, ['twisted.trial.test.test_test_visitor']) | |
| 291 | |
| 292 def test_getTestModules_noVars(self): | |
| 293 modules = trial.getTestModules(sibpath('novars.py')) | |
| 294 self.failUnlessEqual(len(modules), 0) | |
| 295 | |
| 296 def test_getTestModules_multiple(self): | |
| 297 modules = trial.getTestModules(sibpath('scripttest.py')) | |
| 298 self.failUnlessEqual(set(modules), | |
| 299 set(['twisted.trial.test.test_test_visitor', | |
| 300 'twisted.trial.test.test_class'])) | |
| 301 | |
| 302 def test_looksLikeTestModule(self): | |
| 303 for filename in ['test_script.py', 'twisted/trial/test/test_script.py']: | |
| 304 self.failUnless(trial.isTestFile(filename), | |
| 305 "%r should be a test file" % (filename,)) | |
| 306 for filename in ['twisted/trial/test/moduletest.py', | |
| 307 sibpath('scripttest.py'), sibpath('test_foo.bat')]: | |
| 308 self.failIf(trial.isTestFile(filename), | |
| 309 "%r should *not* be a test file" % (filename,)) | |
| 310 | |
| 311 | |
| 312 class WithoutModuleTests(unittest.TestCase): | |
| 313 """ | |
| 314 Test the C{without-module} flag. | |
| 315 """ | |
| 316 | |
| 317 def setUp(self): | |
| 318 """ | |
| 319 Create a L{trial.Options} object to be used in the tests, and save | |
| 320 C{sys.modules}. | |
| 321 """ | |
| 322 self.config = trial.Options() | |
| 323 self.savedModules = dict(sys.modules) | |
| 324 | |
| 325 | |
| 326 def tearDown(self): | |
| 327 """ | |
| 328 Restore C{sys.modules}. | |
| 329 """ | |
| 330 for module in ('imaplib', 'smtplib'): | |
| 331 if module in self.savedModules: | |
| 332 sys.modules[module] = self.savedModules[module] | |
| 333 else: | |
| 334 sys.modules.pop(module, None) | |
| 335 | |
| 336 | |
| 337 def _checkSMTP(self): | |
| 338 """ | |
| 339 Try to import the C{smtplib} module, and return it. | |
| 340 """ | |
| 341 import smtplib | |
| 342 return smtplib | |
| 343 | |
| 344 | |
| 345 def _checkIMAP(self): | |
| 346 """ | |
| 347 Try to import the C{imaplib} module, and return it. | |
| 348 """ | |
| 349 import imaplib | |
| 350 return imaplib | |
| 351 | |
| 352 | |
| 353 def test_disableOneModule(self): | |
| 354 """ | |
| 355 Check that after disabling a module, it can't be imported anymore. | |
| 356 """ | |
| 357 self.config.parseOptions(["--without-module", "smtplib"]) | |
| 358 self.assertRaises(ImportError, self._checkSMTP) | |
| 359 # Restore sys.modules | |
| 360 del sys.modules["smtplib"] | |
| 361 # Then the function should succeed | |
| 362 self.assertIsInstance(self._checkSMTP(), types.ModuleType) | |
| 363 | |
| 364 | |
| 365 def test_disableMultipleModules(self): | |
| 366 """ | |
| 367 Check that several modules can be disabled at once. | |
| 368 """ | |
| 369 self.config.parseOptions(["--without-module", "smtplib,imaplib"]) | |
| 370 self.assertRaises(ImportError, self._checkSMTP) | |
| 371 self.assertRaises(ImportError, self._checkIMAP) | |
| 372 # Restore sys.modules | |
| 373 del sys.modules["smtplib"] | |
| 374 del sys.modules["imaplib"] | |
| 375 # Then the functions should succeed | |
| 376 self.assertIsInstance(self._checkSMTP(), types.ModuleType) | |
| 377 self.assertIsInstance(self._checkIMAP(), types.ModuleType) | |
| 378 | |
| 379 | |
| 380 def test_disableAlreadyImportedModule(self): | |
| 381 """ | |
| 382 Disabling an already imported module should produce a warning. | |
| 383 """ | |
| 384 self.assertIsInstance(self._checkSMTP(), types.ModuleType) | |
| 385 self.assertWarns(RuntimeWarning, | |
| 386 "Module 'smtplib' already imported, disabling anyway.", | |
| 387 trial.__file__, | |
| 388 self.config.parseOptions, ["--without-module", "smtplib"]) | |
| 389 self.assertRaises(ImportError, self._checkSMTP) | |
| 390 | |
| OLD | NEW |