Ticket #4788: skipped_test_deco_r8127.diff
File skipped_test_deco_r8127.diff, 11.0 KB (added by , 16 years ago) |
---|
-
django/test/simple.py
1 import unittest1 import sys, time, traceback, unittest 2 2 from django.conf import settings 3 3 from django.db.models import get_app, get_apps 4 4 from django.test import _doctest as doctest … … 140 140 141 141 old_name = settings.DATABASE_NAME 142 142 create_test_db(verbosity, autoclobber=not interactive) 143 result = unittest.TextTestRunner(verbosity=verbosity).run(suite)143 result = SkipTestRunner(verbosity=verbosity).run(suite) 144 144 destroy_test_db(old_name, verbosity) 145 145 146 146 teardown_test_environment() 147 147 148 148 return len(result.failures) + len(result.errors) 149 150 class 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 195 class _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) -
django/test/__init__.py
4 4 5 5 from django.test.client import Client 6 6 from django.test.testcases import TestCase 7 8 class 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
1 from django.core import urlresolvers 2 from django.test import SkippedTest 3 4 def 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 for this test not found: %s' % \ 13 (len(required_views) > 1 and 's' or '', ', '.join(required_views)) 14 return conditional_skip(urls_found, reason=reason) 15 16 def 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 for this test not found: %s' % \ 25 (len(required_modules) > 1 and 's' or '', ', '.join(required_modules)) 26 return conditional_skip(modules_found, reason=reason) 27 28 def skip_specific_database(database_engine): 29 def database_check(): 30 from django.conf import settings 31 return database_engine == settings.DATABASE_ENGINE 32 reason = 'Test not run for database engine %s.' % database_engine 33 return conditional_skip(database_check, reason=reason) 34 35 def conditional_skip(required_condition, reason=''): 36 if required_condition(): 37 return lambda x: x 38 else: 39 return skip_test(reason) 40 41 def 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
56 56 """ 57 57 58 58 from django.test import TestCase 59 from django.test.decorators import views_required 59 60 from django.core import mail 60 61 61 62 class PasswordResetTest(TestCase): 62 63 fixtures = ['authtestdata.json'] 63 urls = 'django.contrib.auth.urls'64 64 65 65 def test_email_not_found(self): 66 66 "Error is raised if the provided email address isn't currently registered" … … 69 69 response = self.client.post('/password_reset/', {'email': 'not_a_real_email@email.com'}) 70 70 self.assertContains(response, "That e-mail address doesn't have an associated user account") 71 71 self.assertEquals(len(mail.outbox), 0) 72 test_email_not_found = views_required(required_views=['django.contrib.auth.views.password_reset'])(test_email_not_found) 72 73 73 74 def test_email_found(self): 74 75 "Email is sent if a valid email address is provided for password reset" 75 76 response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'}) 76 77 self.assertEquals(response.status_code, 302) 77 78 self.assertEquals(len(mail.outbox), 1) 79 test_email_found = views_required(required_views=['django.contrib.auth.views.password_reset'])(test_email_found) 80 -
tests/regressiontests/test_decorators/tests.py
1 r""" 2 >>> from django.test import SkippedTest 3 >>> from django.test.decorators import * 4 5 >>> skip_test()(None)(None) 6 Traceback (most recent call last): 7 ... 8 SkippedTest 9 10 >>> skip_test(reason='testing')(None)(None) 11 Traceback (most recent call last): 12 ... 13 SkippedTest: testing 14 15 >>> conditional_skip(lambda: False)(None)(None) 16 Traceback (most recent call last): 17 ... 18 SkippedTest 19 20 >>> conditional_skip(lambda: True)(lambda: True)() 21 True 22 23 """ 24 No newline at end of file -
docs/testing.txt
830 830 This test case will use the contents of ``myapp.test_urls`` as the 831 831 URLconf for the duration of the test case. 832 832 833 Skipping tests bound to fail 834 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 835 836 **New in Django development version** 837 838 Occasionally it's helpful to specify tests that are skipped under certain 839 circumstances. To accomplish this, the Django test framework offers decorators 840 that you can apply to your test methods for them to be conditionally skipped. 841 842 You can supply your own condition function as follows:: 843 844 from django.tests.decorators import * 845 846 class TestUnderCondition(TestCase): 847 848 def _my_condition(): 849 # Condition returning True if test should be run and False if it 850 # should be skipped. 851 852 @conditional_skip(_my_condition, reason='This test should be skipped sometimes') 853 def testOnlyOnTuesday(self): 854 # Test to run if _my_condition evaluates to True 855 856 In addition, the Django test framework supplies a handful of skip conditions that 857 handle commonly used conditions for skipping tests. 858 859 ``views_required(required_views=[])`` 860 Does a ``urlresolver.Reverse`` on the required views supplied. Runs test only if 861 all views in ``required_views`` are in use. 862 863 ``modules_required(required_modules=[])`` 864 Runs tests only if all modules in ``required_modules`` can be imported. 865 866 ``skip_specific_database(database_engine)`` 867 Skips test if ``settings.DATABASE_ENGINE`` is equal to database_engine. 868 869 If a test is skipped, it is added to a skipped category in the test runner and 870 the test results are reported as such:: 871 872 ====================================================================== 873 SKIPPED: test_email_found (django.contrib.auth.tests.basic.PasswordResetTest) 874 ---------------------------------------------------------------------- 875 Traceback (most recent call last): 876 File "/Users/dnaquin/Dropbox/Sandbox/django/django/test/decorators.py", line 43, in _skip 877 raise SkippedTest(reason=reason) 878 SkippedTest: Required view for this test not found: django.contrib.auth.views.password_reset 879 880 ---------------------------------------------------------------------- 881 Ran 408 tests in 339.663s 882 883 FAILED (failures=1, skipped=2) 884 885 833 886 Emptying the test outbox 834 887 ~~~~~~~~~~~~~~~~~~~~~~~~ 835 888