Ticket #4501: 4501-coverage-2.diff

File 4501-coverage-2.diff, 6.5 KB (added by Eric Holscher, 16 years ago)

Very hacky, but it seems to work. Just need to whittle this down, maybe.

  • django/core/management/commands/test.py

    diff --git a/django/core/management/commands/test.py b/django/core/management/commands/test.py
    index 8ebf3da..d7f4caf 100644
    a b  
    11from django.core.management.base import BaseCommand
    22from optparse import make_option
    33import sys
     4from django.test.utils import start_coverage, stop_coverage
    45
    56class Command(BaseCommand):
    67    option_list = BaseCommand.option_list + (
    78        make_option('--noinput', action='store_false', dest='interactive', default=True,
    89            help='Tells Django to NOT prompt the user for input of any kind.'),
     10        make_option('--coverage', action='store_true', dest='coverage', default=False,
     11            help='Tells Django to run coverage analysis on your test modules.'),
    912    )
    1013    help = 'Runs the test suite for the specified applications, or the entire site if no apps are specified.'
    1114    args = '[appname ...]'
    class Command(BaseCommand):  
    1821
    1922        verbosity = int(options.get('verbosity', 1))
    2023        interactive = options.get('interactive', True)
     24        use_coverage = options.get('coverage', False)
    2125        test_runner = get_runner(settings)
    2226
    23         failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive)
     27        if use_coverage:
     28            use_coverage = start_coverage(verbosity)
     29
     30        failures = test_runner(test_labels, verbosity=verbosity,
     31                               interactive=interactive)
     32
    2433        if failures:
    2534            sys.exit(failures)
     35
     36        if use_coverage:
     37            stop_coverage(test_labels)
  • django/test/utils.py

    diff --git a/django/test/utils.py b/django/test/utils.py
    index 29babec..3b70467 100644
    a b def teardown_test_environment():  
    6565
    6666    del mail.outbox
    6767
    68 
    6968def get_runner(settings):
    7069    test_path = settings.TEST_RUNNER.split('.')
    7170    # Allow for Python 2.5 relative paths
    def get_runner(settings):  
    7675    test_module = __import__(test_module_name, {}, {}, test_path[-1])
    7776    test_runner = getattr(test_module, test_path[-1])
    7877    return test_runner
     78
     79def start_coverage(verbosity=1):
     80    """
     81    Try to start running coverage analysis.
     82    This tries to import coverage.py, returning False if it can't import.
     83    """
     84    try:
     85        import coverage
     86        if verbosity > 1:
     87            print "Running test runner with coverage."
     88        coverage.start()
     89    except:
     90        if verbosity > 0:
     91            print "coverage.py module is not available."
     92        return False
     93
     94def stop_coverage(test_labels, exclude_admin=True):
     95    #This was undefined if it wasn't imported.
     96    #If we get to this point, coverage exists (since it was imported in start)
     97    import coverage
     98    coverage.stop()
     99    coverage_models = []
     100    if test_labels:
     101        for label in test_labels:
     102            if '.' in label:
     103                #Test the app, don't know if we really want coverage here.
     104                label = label.split('.')[0]
     105            try:
     106                #This is for the common case of non-runtests
     107                coverage_models.append(__import__(label, globals(), locals(), ['']))
     108                continue
     109            except:
     110                #This is for the runtests case, this makes me feel that they
     111                #should be seperated totally in code :/
     112                for app in ('modeltests','regressiontests'):
     113                    try:
     114                        coverage_models.append(__import__("%s.%s" % (app,label), globals(), locals(), ['']))
     115                    except:
     116                        pass
     117    else:
     118        from django.db.models.loading import get_apps
     119        for app in get_apps():
     120            if not exclude_admin or app.__name__.find('django.contrib') == -1:
     121                coverage_models.append(app)
     122    print '---------------------------------------------------------------'
     123    print ' Unit Test Code Coverage Results'
     124    print '---------------------------------------------------------------'
     125    coverage.report(coverage_models, show_missing=1)
     126    print '---------------------------------------------------------------'
  • tests/runtests.py

    diff --git a/tests/runtests.py b/tests/runtests.py
    index bd7f59b..a7b3ba1 100755
    a b class InvalidModelTestCase(unittest.TestCase):  
    8585        self.assert_(not unexpected, "Unexpected Errors: " + '\n'.join(unexpected))
    8686        self.assert_(not missing, "Missing Errors: " + '\n'.join(missing))
    8787
    88 def django_tests(verbosity, interactive, test_labels):
     88def django_tests(verbosity, interactive, use_coverage, test_labels):
    8989    from django.conf import settings
     90    from django.test.utils import start_coverage, stop_coverage
    9091
    9192    old_installed_apps = settings.INSTALLED_APPS
    9293    old_test_database_name = settings.TEST_DATABASE_NAME
    def django_tests(verbosity, interactive, test_labels):  
    154155        settings.TEST_RUNNER = 'django.test.simple.run_tests'
    155156    test_runner = get_runner(settings)
    156157
     158    if use_coverage:
     159        use_coverage = start_coverage(verbosity)
     160
    157161    failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive, extra_tests=extra_tests)
     162
    158163    if failures:
    159164        sys.exit(failures)
    160165
     166    if use_coverage:
     167        stop_coverage(test_labels, exclude_admin=False)
     168
    161169    # Restore the old settings.
    162170    settings.INSTALLED_APPS = old_installed_apps
    163171    settings.ROOT_URLCONF = old_root_urlconf
    if __name__ == "__main__":  
    176184        help='Verbosity level; 0=minimal output, 1=normal output, 2=all output')
    177185    parser.add_option('--noinput', action='store_false', dest='interactive', default=True,
    178186        help='Tells Django to NOT prompt the user for input of any kind.')
     187    parser.add_option('--coverage', action='store_true', dest='coverage', default=False,
     188        help='Tells Django to run coverage analysis on your test modules.'),
    179189    parser.add_option('--settings',
    180190        help='Python path to settings module, e.g. "myproject.settings". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.')
    181191    options, args = parser.parse_args()
    if __name__ == "__main__":  
    184194    elif "DJANGO_SETTINGS_MODULE" not in os.environ:
    185195        parser.error("DJANGO_SETTINGS_MODULE is not set in the environment. "
    186196                      "Set it or use --settings.")
    187     django_tests(int(options.verbosity), options.interactive, args)
     197    django_tests(int(options.verbosity), options.interactive, options.coverage, args)
Back to Top