Ticket #4788: skipped_test_deco_r8075.diff

File skipped_test_deco_r8075.diff, 7.6 KB (added by devin, 7 years ago)
  • django/test/simple.py

     
    1 import unittest
     1import sys, time, traceback, unittest
    22from django.conf import settings
    33from django.db.models import get_app, get_apps
    44from django.test import _doctest as doctest
     
    140140
    141141    old_name = settings.DATABASE_NAME
    142142    create_test_db(verbosity, autoclobber=not interactive)
    143     result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
     143    result = SkipTestRunner(verbosity=verbosity).run(suite)
    144144    destroy_test_db(old_name, verbosity)
    145145   
    146146    teardown_test_environment()
    147147   
    148148    return len(result.failures) + len(result.errors)
     149
     150class SkipTestRunner:
     151    """
     152    A test runner class that adds a Skipped category in the output layer.
     153   
     154    Modeled after unittest.TextTestRunner.
     155
     156    Similarly to unittest.TextTestRunner, prints summary of the results at the end.
     157    (Including a count of skipped tests.)
     158    """
     159
     160    def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
     161        self.stream = unittest._WritelnDecorator(stream)
     162        self.descriptions = descriptions
     163        self.verbosity = verbosity
     164        self.result = _SkipTestResult(self.stream, descriptions, verbosity)
     165
     166    def run(self, test):
     167        "Run the given test case or test suite."
     168        startTime = time.time()
     169        test.run(self.result)
     170        stopTime = time.time()
     171        timeTaken = stopTime - startTime
     172       
     173        self.result.printErrors()
     174        self.stream.writeln(self.result.separator2)
     175        run = self.result.testsRun
     176        self.stream.writeln('Ran %d test%s in %.3fs' %
     177                (run, run != 1 and 's' or '', timeTaken))
     178        self.stream.writeln()
     179        if not self.result.wasSuccessful():
     180            self.stream.write('FAILED (')
     181            failed, errored, skipped = map(len, (self.result.failures, self.result.errors, self.result.skipped))
     182            if failed:
     183                self.stream.write('failures=%d' % failed)
     184            if errored:
     185                if failed: self.stream.write(', ')
     186                self.stream.write('errors=%d' % errored)
     187            if skipped:
     188                if errored or failed: self.stream.write(', ')
     189                self.stream.write('skipped=%d' % skipped)
     190            self.stream.writeln(')')
     191        else:
     192            self.stream.writeln('OK')
     193        return self.result
     194
     195class _SkipTestResult(unittest._TextTestResult):
     196    """
     197    A test result class that adds a Skipped category in the output layer.
     198   
     199    Modeled after unittest._TextTestResult.
     200   
     201    Similarly to unittest._TextTestResult, prints out the names of tests as they are
     202    run and errors as they occur.
     203    """
     204
     205    def __init__(self, stream, descriptions, verbosity):
     206        unittest._TextTestResult.__init__(self, stream, descriptions, verbosity)
     207        self.skipped = []
     208
     209    def addError(self, test, err):
     210        # Determine if this is a skipped test
     211        tracebacks = traceback.extract_tb(err[2])
     212        if tracebacks[-1][-1].startswith('raise SkippedTest'):
     213            self.skipped.append((test, self._exc_info_to_string(err, test)))
     214            if self.showAll:
     215                self.stream.writeln('SKIPPED')
     216            elif self.dots:
     217                self.stream.write('S')
     218                self.stream.flush()
     219        else:
     220            unittest.TestResult.addError(self, test, err)
     221            if self.showAll:
     222                self.stream.writeln('ERROR')
     223            elif self.dots:
     224                self.stream.write('E')
     225                self.stream.flush()
     226
     227    def printErrors(self):
     228        if self.dots or self.showAll:
     229            self.stream.writeln()
     230        self.printErrorList('SKIPPED', self.skipped)
     231        self.printErrorList('ERROR', self.errors)
     232        self.printErrorList('FAIL', self.failures)
     233
     234    def printErrorList(self, flavour, errors):
     235        for test, err in errors:
     236            self.stream.writeln(self.separator1)
     237            self.stream.writeln('%s: %s' % (flavour, self.getDescription(test)))
     238            self.stream.writeln(self.separator2)
     239            self.stream.writeln('%s' % err)
  • django/test/__init__.py

     
    44
    55from django.test.client import Client
    66from django.test.testcases import TestCase
     7
     8class SkippedTest(Exception):
     9   
     10    def __init__(self, reason):
     11        self.reason = reason
     12       
     13    def __str__(self):
     14        return self.reason
  • django/test/decorators.py

     
     1from django.core import urlresolvers
     2from django.test import SkippedTest
     3
     4def views_required(required_views=[]):
     5    def urls_found():
     6        try:
     7            for view in required_views:
     8                urlresolvers.reverse(view)
     9            return True
     10        except urlresolvers.NoReverseMatch:
     11            return False
     12    reason = 'Required view%s not found: %s' % \
     13            (len(required_views) > 1 and 's' or '', ', '.join(required_views))
     14    return conditional_skip(urls_found, reason=reason)
     15
     16def modules_required(required_modules=[]):
     17    def modules_found():
     18        try:
     19            for module in required_modules:
     20                __import__(module)
     21            return True
     22        except ImportError:
     23            return False
     24    reason = 'Required module%s not found: %s' % \
     25            (len(required_modules) > 1 and 's' or '', ', '.join(required_modules))
     26    return conditional_skip(modules_found, reason=reason)
     27
     28def skip_specific_database(database_engine):
     29    def database_check():
     30        from django.conf import settings
     31        return database_engine == settings.DATABASE_ENGINE
     32    reason = 'Database engine %s not used.' % database_engine
     33    return conditional_skip(database_check, reason=reason)
     34
     35def conditional_skip(required_condition, reason=''):
     36    if required_condition():
     37        return lambda x: x
     38    else:
     39        return skip_test(reason)
     40
     41def skip_test(reason=''):
     42    def _skip(x):
     43        raise SkippedTest(reason=reason)
     44    return lambda x: _skip
     45 No newline at end of file
  • django/contrib/auth/tests/basic.py

     
    5656"""
    5757
    5858from django.test import TestCase
     59from django.test.decorators import views_required
    5960from django.core import mail
    6061
    6162class PasswordResetTest(TestCase):
     
    6970        response = self.client.post('/password_reset/', {'email': 'not_a_real_email@email.com'})
    7071        self.assertContains(response, "That e-mail address doesn't have an associated user account")
    7172        self.assertEquals(len(mail.outbox), 0)
     73    test_email_not_found = views_required(required_views=['django.contrib.auth.views.password_reset'])(test_email_not_found)
    7274   
    7375    def test_email_found(self):
    7476        "Email is sent if a valid email address is provided for password reset"
    7577        response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'})
    7678        self.assertEquals(response.status_code, 302)
    7779        self.assertEquals(len(mail.outbox), 1)
     80    test_email_found = views_required(required_views=['django.contrib.auth.views.password_reset'])(test_email_found)
     81
Back to Top