diff options
Diffstat (limited to 'webapp/django/test/simple.py')
-rw-r--r-- | webapp/django/test/simple.py | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/webapp/django/test/simple.py b/webapp/django/test/simple.py new file mode 100644 index 0000000000..ce9f59e90e --- /dev/null +++ b/webapp/django/test/simple.py @@ -0,0 +1,148 @@ +import unittest +from django.conf import settings +from django.db.models import get_app, get_apps +from django.test import _doctest as doctest +from django.test.utils import setup_test_environment, teardown_test_environment +from django.test.testcases import OutputChecker, DocTestRunner + +# The module name for tests outside models.py +TEST_MODULE = 'tests' + +doctestOutputChecker = OutputChecker() + +def get_tests(app_module): + try: + app_path = app_module.__name__.split('.')[:-1] + test_module = __import__('.'.join(app_path + [TEST_MODULE]), {}, {}, TEST_MODULE) + except ImportError, e: + # Couldn't import tests.py. Was it due to a missing file, or + # due to an import error in a tests.py that actually exists? + import os.path + from imp import find_module + try: + mod = find_module(TEST_MODULE, [os.path.dirname(app_module.__file__)]) + except ImportError: + # 'tests' module doesn't exist. Move on. + test_module = None + else: + # The module exists, so there must be an import error in the + # test module itself. We don't need the module; so if the + # module was a single file module (i.e., tests.py), close the file + # handle returned by find_module. Otherwise, the test module + # is a directory, and there is nothing to close. + if mod[0]: + mod[0].close() + raise + return test_module + +def build_suite(app_module): + "Create a complete Django test suite for the provided application module" + suite = unittest.TestSuite() + + # Load unit and doctests in the models.py module. If module has + # a suite() method, use it. Otherwise build the test suite ourselves. + if hasattr(app_module, 'suite'): + suite.addTest(app_module.suite()) + else: + suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(app_module)) + try: + suite.addTest(doctest.DocTestSuite(app_module, + checker=doctestOutputChecker, + runner=DocTestRunner)) + except ValueError: + # No doc tests in models.py + pass + + # Check to see if a separate 'tests' module exists parallel to the + # models module + test_module = get_tests(app_module) + if test_module: + # Load unit and doctests in the tests.py module. If module has + # a suite() method, use it. Otherwise build the test suite ourselves. + if hasattr(test_module, 'suite'): + suite.addTest(test_module.suite()) + else: + suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(test_module)) + try: + suite.addTest(doctest.DocTestSuite(test_module, + checker=doctestOutputChecker, + runner=DocTestRunner)) + except ValueError: + # No doc tests in tests.py + pass + return suite + +def build_test(label): + """Construct a test case a test with the specified label. Label should + be of the form model.TestClass or model.TestClass.test_method. Returns + an instantiated test or test suite corresponding to the label provided. + + """ + parts = label.split('.') + if len(parts) < 2 or len(parts) > 3: + raise ValueError("Test label '%s' should be of the form app.TestCase or app.TestCase.test_method" % label) + + app_module = get_app(parts[0]) + TestClass = getattr(app_module, parts[1], None) + + # Couldn't find the test class in models.py; look in tests.py + if TestClass is None: + test_module = get_tests(app_module) + if test_module: + TestClass = getattr(test_module, parts[1], None) + + if len(parts) == 2: # label is app.TestClass + try: + return unittest.TestLoader().loadTestsFromTestCase(TestClass) + except TypeError: + raise ValueError("Test label '%s' does not refer to a test class" % label) + else: # label is app.TestClass.test_method + return TestClass(parts[2]) + +def run_tests(test_labels, verbosity=1, interactive=True, extra_tests=[]): + """ + Run the unit tests for all the test labels in the provided list. + Labels must be of the form: + - app.TestClass.test_method + Run a single specific test method + - app.TestClass + Run all the test methods in a given class + - app + Search for doctests and unittests in the named application. + + When looking for tests, the test runner will look in the models and + tests modules for the application. + + A list of 'extra' tests may also be provided; these tests + will be added to the test suite. + + Returns the number of tests that failed. + """ + setup_test_environment() + + settings.DEBUG = False + suite = unittest.TestSuite() + + if test_labels: + for label in test_labels: + if '.' in label: + suite.addTest(build_test(label)) + else: + app = get_app(label) + suite.addTest(build_suite(app)) + else: + for app in get_apps(): + suite.addTest(build_suite(app)) + + for test in extra_tests: + suite.addTest(test) + + old_name = settings.DATABASE_NAME + from django.db import connection + connection.creation.create_test_db(verbosity, autoclobber=not interactive) + result = unittest.TextTestRunner(verbosity=verbosity).run(suite) + connection.creation.destroy_test_db(old_name, verbosity) + + teardown_test_environment() + + return len(result.failures) + len(result.errors) |