Django

Code

Ticket #506: runtests-granular.patch

File runtests-granular.patch, 6.3 kB (added by Simon Willison, 3 years ago)

runtests.py patch.

  • runtests.py

    old new  
    1212TEST_DATABASE_NAME = 'django_test_db' 
    1313 
    1414error_list = [] 
     15 
    1516def log_error(model_name, title, description): 
    1617    error_list.append({ 
    1718        'title': "%r module: %s" % (model_name, title), 
     
    5455        return ok 
    5556 
    5657class TestRunner: 
    57     def __init__(self, verbosity_level=0): 
     58    def __init__(self, verbosity_level=0, which_tests=None): 
    5859        self.verbosity_level = verbosity_level 
     60        self.which_tests = which_tests 
    5961 
    6062    def output(self, required_level, message): 
    6163        if self.verbosity_level > required_level - 1: 
     
    6668        from django.core.db import db 
    6769        from django.core import management, meta 
    6870 
    69         self.output(0, "Running tests with database %r" % settings.DATABASE_ENGINE) 
    70  
    7171        # Manually set INSTALLED_APPS to point to the test app. 
    7272        settings.INSTALLED_APPS = (APP_NAME,) 
    7373 
     74        # Work out which models we are going to test 
     75        test_models = get_test_models() 
     76        if self.which_tests: 
     77            # Only run the specified tests 
     78            bad_models = [m for m in self.which_tests if m not in test_models] 
     79            if bad_models: 
     80                print >> sys.stderr, "Models not found: %s" % bad_models 
     81                sys.exit(1) 
     82            else: 
     83                test_models = self.which_tests 
     84 
     85        self.output(0, "Running tests with database %r" % settings.DATABASE_ENGINE) 
     86 
    7487        # If we're using SQLite, it's more convenient to test against an 
    7588        # in-memory database. 
    7689        if settings.DATABASE_ENGINE == "sqlite3": 
     
    107120 
    108121        # Run the tests for each test model. 
    109122        self.output(1, "Running app tests") 
    110         for model_name in get_test_models()
     123        for model_name in test_models
    111124            self.output(1, "%s model: Importing" % model_name) 
    112125            try: 
    113126                mod = meta.get_app(model_name) 
     
    132145                # side effects on other tests. 
    133146                db.rollback() 
    134147 
    135         # Run the non-model tests in the other tests dir 
    136         self.output(1, "Running other tests") 
    137         other_tests_dir = os.path.join(os.path.dirname(__file__), OTHER_TESTS_DIR) 
    138         test_modules = [f[:-3] for f in os.listdir(other_tests_dir) if f.endswith('.py') and not f.startswith('__init__')] 
    139         for module in test_modules: 
    140             self.output(1, "%s module: Importing" % module) 
    141             try: 
    142                 mod = __import__("othertests." + module, '', '', ['']) 
    143             except Exception, e: 
    144                 log_error(module, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:])) 
    145                 continue 
    146             if mod.__doc__: 
    147                 p = doctest.DocTestParser() 
    148                 dtest = p.get_doctest(mod.__doc__, mod.__dict__, module, None, None) 
    149                 runner = DjangoDoctestRunner(verbosity_level=verbosity_level, verbose=False) 
    150                 self.output(1, "%s module: runing tests" % module) 
    151                 runner.run(dtest, clear_globs=True, out=sys.stdout.write) 
    152             if hasattr(mod, "run_tests") and callable(mod.run_tests): 
    153                 self.output(1, "%s module: runing tests" % module) 
     148 
     149        if not self.which_tests: 
     150            # Run the non-model tests in the other tests dir 
     151            self.output(1, "Running other tests") 
     152            other_tests_dir = os.path.join(os.path.dirname(__file__), OTHER_TESTS_DIR) 
     153            test_modules = [f[:-3] for f in os.listdir(other_tests_dir) if f.endswith('.py') and not f.startswith('__init__')] 
     154            for module in test_modules: 
     155                self.output(1, "%s module: Importing" % module) 
    154156                try: 
    155                     mod.run_tests(verbosity_level
     157                    mod = __import__("othertests." + module, '', '', ['']
    156158                except Exception, e: 
    157                     log_error(module, "Exception running tests", ''.join(traceback.format_exception(*sys.exc_info())[1:])) 
     159                    log_error(module, "Error while importing", ''.join(traceback.format_exception(*sys.exc_info())[1:])) 
    158160                    continue 
     161                if mod.__doc__: 
     162                    p = doctest.DocTestParser() 
     163                    dtest = p.get_doctest(mod.__doc__, mod.__dict__, module, None, None) 
     164                    runner = DjangoDoctestRunner(verbosity_level=verbosity_level, verbose=False) 
     165                    self.output(1, "%s module: runing tests" % module) 
     166                    runner.run(dtest, clear_globs=True, out=sys.stdout.write) 
     167                if hasattr(mod, "run_tests") and callable(mod.run_tests): 
     168                    self.output(1, "%s module: runing tests" % module) 
     169                    try: 
     170                        mod.run_tests(verbosity_level) 
     171                    except Exception, e: 
     172                        log_error(module, "Exception running tests", ''.join(traceback.format_exception(*sys.exc_info())[1:])) 
     173                        continue 
    159174 
    160175        # Unless we're using SQLite, remove the test database to clean up after 
    161176        # ourselves. Connect to the previous database (not the test database) 
     
    176191 
    177192        # Display output. 
    178193        if error_list: 
    179             print "Got %s error%s:" % (len(error_list), len(error_list) != 1 and 's' or '') 
    180194            for d in error_list: 
    181195                print 
    182196                print d['title'] 
    183197                print "=" * len(d['title']) 
    184198                print d['description'] 
     199            print "%s error%s" % (len(error_list), len(error_list) != 1 and 's' or '') 
    185200        else: 
    186201            print "All tests passed." 
    187202 
    188203if __name__ == "__main__": 
    189204    from optparse import OptionParser 
    190     parser = OptionParser() 
     205    usage = "%prog [options] [test_model]..." 
     206    parser = OptionParser(usage=usage) 
    191207    parser.add_option('-v', help='How verbose should the output be? Choices are 0, 1 and 2, where 2 is most verbose. Default is 0.', 
    192208        type='choice', choices=['0', '1', '2']) 
    193209    parser.add_option('--settings', 
     
    198214        verbosity_level = int(options.v) 
    199215    if options.settings: 
    200216        os.environ['DJANGO_SETTINGS_MODULE'] = options.settings 
    201     t = TestRunner(verbosity_level
     217    t = TestRunner(verbosity_level, args
    202218    t.run_tests()