PageRenderTime 59ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/servicios_web/gae/django-guestbook/src/django/test/simple.py

https://github.com/navarro81/curso_python_dga_11
Python | 289 lines | 190 code | 30 blank | 69 comment | 53 complexity | 98c6a20461f072852f6fa69749895386 MD5 | raw file
  1. import sys
  2. import signal
  3. from django.conf import settings
  4. from django.db.models import get_app, get_apps
  5. from django.test import _doctest as doctest
  6. from django.test.utils import setup_test_environment, teardown_test_environment
  7. from django.test.testcases import OutputChecker, DocTestRunner, TestCase
  8. from django.utils import unittest
  9. # The module name for tests outside models.py
  10. TEST_MODULE = 'tests'
  11. doctestOutputChecker = OutputChecker()
  12. class DjangoTestRunner(unittest.TextTestRunner):
  13. def __init__(self, *args, **kwargs):
  14. import warnings
  15. warnings.warn(
  16. "DjangoTestRunner is deprecated; it's functionality is indistinguishable from TextTestRunner",
  17. PendingDeprecationWarning
  18. )
  19. super(DjangoTestRunner, self).__init__(*args, **kwargs)
  20. def get_tests(app_module):
  21. try:
  22. app_path = app_module.__name__.split('.')[:-1]
  23. test_module = __import__('.'.join(app_path + [TEST_MODULE]), {}, {}, TEST_MODULE)
  24. except ImportError, e:
  25. # Couldn't import tests.py. Was it due to a missing file, or
  26. # due to an import error in a tests.py that actually exists?
  27. import os.path
  28. from imp import find_module
  29. try:
  30. mod = find_module(TEST_MODULE, [os.path.dirname(app_module.__file__)])
  31. except ImportError:
  32. # 'tests' module doesn't exist. Move on.
  33. test_module = None
  34. else:
  35. # The module exists, so there must be an import error in the
  36. # test module itself. We don't need the module; so if the
  37. # module was a single file module (i.e., tests.py), close the file
  38. # handle returned by find_module. Otherwise, the test module
  39. # is a directory, and there is nothing to close.
  40. if mod[0]:
  41. mod[0].close()
  42. raise
  43. return test_module
  44. def build_suite(app_module):
  45. "Create a complete Django test suite for the provided application module"
  46. suite = unittest.TestSuite()
  47. # Load unit and doctests in the models.py module. If module has
  48. # a suite() method, use it. Otherwise build the test suite ourselves.
  49. if hasattr(app_module, 'suite'):
  50. suite.addTest(app_module.suite())
  51. else:
  52. suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(app_module))
  53. try:
  54. suite.addTest(doctest.DocTestSuite(app_module,
  55. checker=doctestOutputChecker,
  56. runner=DocTestRunner))
  57. except ValueError:
  58. # No doc tests in models.py
  59. pass
  60. # Check to see if a separate 'tests' module exists parallel to the
  61. # models module
  62. test_module = get_tests(app_module)
  63. if test_module:
  64. # Load unit and doctests in the tests.py module. If module has
  65. # a suite() method, use it. Otherwise build the test suite ourselves.
  66. if hasattr(test_module, 'suite'):
  67. suite.addTest(test_module.suite())
  68. else:
  69. suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(test_module))
  70. try:
  71. suite.addTest(doctest.DocTestSuite(test_module,
  72. checker=doctestOutputChecker,
  73. runner=DocTestRunner))
  74. except ValueError:
  75. # No doc tests in tests.py
  76. pass
  77. return suite
  78. def build_test(label):
  79. """Construct a test case with the specified label. Label should be of the
  80. form model.TestClass or model.TestClass.test_method. Returns an
  81. instantiated test or test suite corresponding to the label provided.
  82. """
  83. parts = label.split('.')
  84. if len(parts) < 2 or len(parts) > 3:
  85. raise ValueError("Test label '%s' should be of the form app.TestCase or app.TestCase.test_method" % label)
  86. #
  87. # First, look for TestCase instances with a name that matches
  88. #
  89. app_module = get_app(parts[0])
  90. test_module = get_tests(app_module)
  91. TestClass = getattr(app_module, parts[1], None)
  92. # Couldn't find the test class in models.py; look in tests.py
  93. if TestClass is None:
  94. if test_module:
  95. TestClass = getattr(test_module, parts[1], None)
  96. try:
  97. if issubclass(TestClass, unittest.TestCase):
  98. if len(parts) == 2: # label is app.TestClass
  99. try:
  100. return unittest.TestLoader().loadTestsFromTestCase(TestClass)
  101. except TypeError:
  102. raise ValueError("Test label '%s' does not refer to a test class" % label)
  103. else: # label is app.TestClass.test_method
  104. return TestClass(parts[2])
  105. except TypeError:
  106. # TestClass isn't a TestClass - it must be a method or normal class
  107. pass
  108. #
  109. # If there isn't a TestCase, look for a doctest that matches
  110. #
  111. tests = []
  112. for module in app_module, test_module:
  113. try:
  114. doctests = doctest.DocTestSuite(module,
  115. checker=doctestOutputChecker,
  116. runner=DocTestRunner)
  117. # Now iterate over the suite, looking for doctests whose name
  118. # matches the pattern that was given
  119. for test in doctests:
  120. if test._dt_test.name in (
  121. '%s.%s' % (module.__name__, '.'.join(parts[1:])),
  122. '%s.__test__.%s' % (module.__name__, '.'.join(parts[1:]))):
  123. tests.append(test)
  124. except ValueError:
  125. # No doctests found.
  126. pass
  127. # If no tests were found, then we were given a bad test label.
  128. if not tests:
  129. raise ValueError("Test label '%s' does not refer to a test" % label)
  130. # Construct a suite out of the tests that matched.
  131. return unittest.TestSuite(tests)
  132. def partition_suite(suite, classes, bins):
  133. """
  134. Partitions a test suite by test type.
  135. classes is a sequence of types
  136. bins is a sequence of TestSuites, one more than classes
  137. Tests of type classes[i] are added to bins[i],
  138. tests with no match found in classes are place in bins[-1]
  139. """
  140. for test in suite:
  141. if isinstance(test, unittest.TestSuite):
  142. partition_suite(test, classes, bins)
  143. else:
  144. for i in range(len(classes)):
  145. if isinstance(test, classes[i]):
  146. bins[i].addTest(test)
  147. break
  148. else:
  149. bins[-1].addTest(test)
  150. def reorder_suite(suite, classes):
  151. """
  152. Reorders a test suite by test type.
  153. classes is a sequence of types
  154. All tests of type clases[0] are placed first, then tests of type classes[1], etc.
  155. Tests with no match in classes are placed last.
  156. """
  157. class_count = len(classes)
  158. bins = [unittest.TestSuite() for i in range(class_count+1)]
  159. partition_suite(suite, classes, bins)
  160. for i in range(class_count):
  161. bins[0].addTests(bins[i+1])
  162. return bins[0]
  163. class DjangoTestSuiteRunner(object):
  164. def __init__(self, verbosity=1, interactive=True, failfast=True, **kwargs):
  165. self.verbosity = verbosity
  166. self.interactive = interactive
  167. self.failfast = failfast
  168. def setup_test_environment(self, **kwargs):
  169. setup_test_environment()
  170. settings.DEBUG = False
  171. unittest.installHandler()
  172. def build_suite(self, test_labels, extra_tests=None, **kwargs):
  173. suite = unittest.TestSuite()
  174. if test_labels:
  175. for label in test_labels:
  176. if '.' in label:
  177. suite.addTest(build_test(label))
  178. else:
  179. app = get_app(label)
  180. suite.addTest(build_suite(app))
  181. else:
  182. for app in get_apps():
  183. suite.addTest(build_suite(app))
  184. if extra_tests:
  185. for test in extra_tests:
  186. suite.addTest(test)
  187. return reorder_suite(suite, (TestCase,))
  188. def setup_databases(self, **kwargs):
  189. from django.db import connections
  190. old_names = []
  191. mirrors = []
  192. for alias in connections:
  193. connection = connections[alias]
  194. # If the database is a test mirror, redirect it's connection
  195. # instead of creating a test database.
  196. if connection.settings_dict['TEST_MIRROR']:
  197. mirrors.append((alias, connection))
  198. mirror_alias = connection.settings_dict['TEST_MIRROR']
  199. connections._connections[alias] = connections[mirror_alias]
  200. else:
  201. old_names.append((connection, connection.settings_dict['NAME']))
  202. connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive)
  203. return old_names, mirrors
  204. def run_suite(self, suite, **kwargs):
  205. return unittest.TextTestRunner(verbosity=self.verbosity, failfast=self.failfast).run(suite)
  206. def teardown_databases(self, old_config, **kwargs):
  207. from django.db import connections
  208. old_names, mirrors = old_config
  209. # Point all the mirrors back to the originals
  210. for alias, connection in mirrors:
  211. connections._connections[alias] = connection
  212. # Destroy all the non-mirror databases
  213. for connection, old_name in old_names:
  214. connection.creation.destroy_test_db(old_name, self.verbosity)
  215. def teardown_test_environment(self, **kwargs):
  216. unittest.removeHandler()
  217. teardown_test_environment()
  218. def suite_result(self, suite, result, **kwargs):
  219. return len(result.failures) + len(result.errors)
  220. def run_tests(self, test_labels, extra_tests=None, **kwargs):
  221. """
  222. Run the unit tests for all the test labels in the provided list.
  223. Labels must be of the form:
  224. - app.TestClass.test_method
  225. Run a single specific test method
  226. - app.TestClass
  227. Run all the test methods in a given class
  228. - app
  229. Search for doctests and unittests in the named application.
  230. When looking for tests, the test runner will look in the models and
  231. tests modules for the application.
  232. A list of 'extra' tests may also be provided; these tests
  233. will be added to the test suite.
  234. Returns the number of tests that failed.
  235. """
  236. self.setup_test_environment()
  237. suite = self.build_suite(test_labels, extra_tests)
  238. old_config = self.setup_databases()
  239. result = self.run_suite(suite)
  240. self.teardown_databases(old_config)
  241. self.teardown_test_environment()
  242. return self.suite_result(suite, result)
  243. def run_tests(test_labels, verbosity=1, interactive=True, failfast=False, extra_tests=None):
  244. import warnings
  245. warnings.warn(
  246. 'The run_tests() test runner has been deprecated in favor of DjangoTestSuiteRunner.',
  247. DeprecationWarning
  248. )
  249. test_runner = DjangoTestSuiteRunner(verbosity=verbosity, interactive=interactive, failfast=failfast)
  250. return test_runner.run_tests(test_labels, extra_tests=extra_tests)