Ticket #8138: 8138reorder-suite.diff
File 8138reorder-suite.diff, 22.1 KB (added by , 16 years ago) |
---|
-
django/test/simple.py
3 3 from django.db.models import get_app, get_apps 4 4 from django.test import _doctest as doctest 5 5 from django.test.utils import setup_test_environment, teardown_test_environment 6 from django.test.testcases import OutputChecker, DocTestRunner 6 from django.test.testcases import OutputChecker, DocTestRunner, TestCase 7 7 8 8 # The module name for tests outside models.py 9 9 TEST_MODULE = 'tests' … … 99 99 else: # label is app.TestClass.test_method 100 100 return TestClass(parts[2]) 101 101 102 def partition_suite(suite, classes, bins): 103 """ 104 Partitions a test suite by test type. 105 106 classes is a sequence of types 107 bins is a sequence of TestSuites, one more than classes 108 109 Tests of type classes[i] are added to bins[i], 110 tests with no match found in classes are place in bins[-1] 111 """ 112 for test in suite: 113 if isinstance(test, unittest.TestSuite): 114 partition_suite(test, classes, bins) 115 else: 116 for i in range(len(classes)): 117 if isinstance(test, classes[i]): 118 bins[i].addTest(test) 119 break 120 else: 121 bins[-1].addTest(test) 122 123 def reorder_suite(suite, classes): 124 """ 125 Reorders a test suite by test type. 126 127 classes is a sequence of types 128 129 All tests of type clases[0] are placed first, then tests of type classes[1], etc. 130 Tests with no match in classes are placed last. 131 """ 132 class_count = len(classes) 133 bins = [unittest.TestSuite() for i in range(class_count+1)] 134 partition_suite(suite, classes, bins) 135 for i in range(class_count): 136 bins[0].addTests(bins[i+1]) 137 return bins[0] 138 102 139 def run_tests(test_labels, verbosity=1, interactive=True, extra_tests=[]): 103 140 """ 104 141 Run the unit tests for all the test labels in the provided list. … … 137 174 for test in extra_tests: 138 175 suite.addTest(test) 139 176 177 suite = reorder_suite(suite, (TestCase,)) 178 140 179 old_name = settings.DATABASE_NAME 141 180 from django.db import connection 142 181 connection.creation.create_test_db(verbosity, autoclobber=not interactive) -
django/test/client.py
19 19 from django.utils.encoding import smart_str 20 20 from django.utils.http import urlencode 21 21 from django.utils.itercompat import is_iterable 22 from django.db import transaction, close_connection 22 23 23 24 BOUNDARY = 'BoUnDaRyStRiNg' 24 25 MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY … … 69 70 response = middleware_method(request, response) 70 71 response = self.apply_response_fixes(request, response) 71 72 finally: 73 signals.request_finished.disconnect(close_connection) 72 74 signals.request_finished.send(sender=self.__class__) 75 signals.request_finished.connect(close_connection) 73 76 74 77 return response 75 78 -
django/test/testcases.py
7 7 from django.core import mail 8 8 from django.core.management import call_command 9 9 from django.core.urlresolvers import clear_url_caches 10 from django.db import transaction 10 from django.db import transaction, connection 11 11 from django.http import QueryDict 12 12 from django.test import _doctest as doctest 13 13 from django.test.client import Client … … 26 26 value = [value] 27 27 return value 28 28 29 real_commit = transaction.commit 30 real_rollback = transaction.rollback 31 real_enter_transaction_management = transaction.enter_transaction_management 32 real_leave_transaction_management = transaction.leave_transaction_management 33 real_savepoint_commit = transaction.savepoint_commit 34 real_savepoint_rollback = transaction.savepoint_rollback 29 35 36 def nop(x=None): 37 return 38 39 def disable_transaction_methods(): 40 transaction.commit = nop 41 transaction.rollback = nop 42 transaction.savepoint_commit = nop 43 transaction.savepoint_rollback = nop 44 transaction.enter_transaction_management = nop 45 transaction.leave_transaction_management = nop 46 47 def restore_transaction_methods(): 48 transaction.commit = real_commit 49 transaction.rollback = real_rollback 50 transaction.savepoint_commit = real_savepoint_commit 51 transaction.savepoint_rollback = real_savepoint_rollback 52 transaction.enter_transaction_management = real_enter_transaction_management 53 transaction.leave_transaction_management = real_leave_transaction_management 54 30 55 class OutputChecker(doctest.OutputChecker): 31 56 def check_output(self, want, got, optionflags): 32 57 "The entry method for doctest output checking. Defers to a sequence of child checkers" … … 168 193 # Rollback, in case of database errors. Otherwise they'd have 169 194 # side effects on other tests. 170 195 transaction.rollback_unless_managed() 171 172 class T estCase(unittest.TestCase):196 197 class TransactionTestCase(unittest.TestCase): 173 198 def _pre_setup(self): 174 199 """Performs any pre-test setup. This includes: 175 200 … … 180 205 ROOT_URLCONF with it. 181 206 * Clearing the mail test outbox. 182 207 """ 208 self._fixture_setup() 209 self._urlconf_setup() 210 mail.outbox = [] 211 212 def _fixture_setup(self): 183 213 call_command('flush', verbosity=0, interactive=False) 184 214 if hasattr(self, 'fixtures'): 185 215 # We have to use this slightly awkward syntax due to the fact 186 216 # that we're using *args and **kwargs together. 187 217 call_command('loaddata', *self.fixtures, **{'verbosity': 0}) 218 219 def _urlconf_setup(self): 188 220 if hasattr(self, 'urls'): 189 221 self._old_root_urlconf = settings.ROOT_URLCONF 190 222 settings.ROOT_URLCONF = self.urls 191 223 clear_url_caches() 192 mail.outbox = []193 224 194 225 def __call__(self, result=None): 195 226 """ … … 206 237 import sys 207 238 result.addError(self, sys.exc_info()) 208 239 return 209 super(T estCase, self).__call__(result)240 super(TransactionTestCase, self).__call__(result) 210 241 try: 211 242 self._post_teardown() 212 243 except (KeyboardInterrupt, SystemExit): … … 221 252 222 253 * Putting back the original ROOT_URLCONF if it was changed. 223 254 """ 255 self._fixture_teardown() 256 self._urlconf_teardown() 257 258 def _fixture_teardown(self): 259 pass 260 261 def _urlconf_teardown(self): 224 262 if hasattr(self, '_old_root_urlconf'): 225 263 settings.ROOT_URLCONF = self._old_root_urlconf 226 264 clear_url_caches() … … 354 392 self.failIf(template_name in template_names, 355 393 (u"Template '%s' was used unexpectedly in rendering the" 356 394 u" response") % template_name) 395 396 class TestCase(TransactionTestCase): 397 """ 398 Does basically the same as TransactionTestCase, but surrounds every test 399 with a transaction, monkey-patches the real transaction management routines to 400 do nothing, and rollsback the test transaction at the end of the test. You have 401 to use TransactionTestCase, if you need transaction management inside a test. 402 """ 403 404 def _fixture_setup(self): 405 if not settings.DATABASE_SUPPORTS_TRANSACTIONS: 406 return super(TestCase, self)._fixture_setup() 407 408 transaction.enter_transaction_management() 409 transaction.managed(True) 410 disable_transaction_methods() 411 412 from django.contrib.sites.models import Site 413 Site.objects.clear_cache() 414 415 if hasattr(self, 'fixtures'): 416 call_command('loaddata', *self.fixtures, **{ 417 'verbosity': 0, 418 'commit': False 419 }) 420 421 def _fixture_teardown(self): 422 if not settings.DATABASE_SUPPORTS_TRANSACTIONS: 423 return super(TestCase, self)._fixture_teardown() 424 425 restore_transaction_methods() 426 transaction.rollback() 427 transaction.leave_transaction_management() 428 No newline at end of file -
django/test/__init__.py
3 3 """ 4 4 5 5 from django.test.client import Client 6 from django.test.testcases import TestCase 6 from django.test.testcases import TestCase, TransactionTestCase -
django/db/backends/creation.py
311 311 312 312 self.connection.close() 313 313 settings.DATABASE_NAME = test_database_name 314 314 settings.DATABASE_SUPPORTS_TRANSACTIONS = self._rollback_works() 315 315 316 call_command('syncdb', verbosity=verbosity, interactive=False) 316 317 317 318 if settings.CACHE_BACKEND.startswith('db://'): … … 362 363 sys.exit(1) 363 364 364 365 return test_database_name 365 366 367 def _rollback_works(self): 368 cursor = self.connection.cursor() 369 cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)') 370 self.connection._commit() 371 cursor.execute('INSERT INTO ROLLBACK_TEST (X) VALUES (8)') 372 self.connection._rollback() 373 cursor.execute('SELECT COUNT(X) FROM ROLLBACK_TEST') 374 count, = cursor.fetchone() 375 cursor.execute('DROP TABLE ROLLBACK_TEST') 376 self.connection._commit() 377 return count == 0 378 366 379 def destroy_test_db(self, old_database_name, verbosity=1): 367 380 """ 368 381 Destroy a test database, prompting the user for confirmation if the -
tests/regressiontests/file_uploads/tests.py
238 238 self.obj = FileModel() 239 239 if not os.path.isdir(temp_storage.location): 240 240 os.makedirs(temp_storage.location) 241 if os.path.isdir(UPLOAD_TO): 242 os.chmod(UPLOAD_TO, 0700) 243 shutil.rmtree(UPLOAD_TO) 241 244 242 245 def tearDown(self): 243 246 os.chmod(temp_storage.location, 0700) -
tests/regressiontests/generic_inline_admin/tests.py
21 21 # relies on content type IDs, which will vary depending on what 22 22 # other tests have been run), thus we do it here. 23 23 e = Episode.objects.create(name='This Week in Django') 24 self.episode_pk = e.pk 24 25 m = Media(content_object=e, url='http://example.com/podcast.mp3') 25 26 m.save() 27 self.media_pk = m.pk 26 28 27 29 def tearDown(self): 28 30 self.client.logout() … … 39 41 """ 40 42 A smoke test to ensure GET on the change_view works. 41 43 """ 42 response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/ 1/')44 response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk) 43 45 self.failUnlessEqual(response.status_code, 200) 44 46 45 47 def testBasicAddPost(self): … … 64 66 # inline data 65 67 "generic_inline_admin-media-content_type-object_id-TOTAL_FORMS": u"2", 66 68 "generic_inline_admin-media-content_type-object_id-INITIAL_FORMS": u"1", 67 "generic_inline_admin-media-content_type-object_id-0-id": u" 1",69 "generic_inline_admin-media-content_type-object_id-0-id": u"%d" % self.media_pk, 68 70 "generic_inline_admin-media-content_type-object_id-0-url": u"http://example.com/podcast.mp3", 69 71 "generic_inline_admin-media-content_type-object_id-1-id": u"", 70 72 "generic_inline_admin-media-content_type-object_id-1-url": u"", 71 73 } 72 response = self.client.post('/generic_inline_admin/admin/generic_inline_admin/episode/1/', post_data) 74 url = '/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk 75 response = self.client.post(url, post_data) 73 76 self.failUnlessEqual(response.status_code, 302) # redirect somewhere -
tests/regressiontests/comment_tests/tests/moderation_view_tests.py
8 8 9 9 def testFlagGet(self): 10 10 """GET the flag view: render a confirmation page.""" 11 self.createSomeComments() 11 comments = self.createSomeComments() 12 pk = comments[0].pk 12 13 self.client.login(username="normaluser", password="normaluser") 13 response = self.client.get("/flag/ 1/")14 response = self.client.get("/flag/%d/" % pk) 14 15 self.assertTemplateUsed(response, "comments/flag.html") 15 16 16 17 def testFlagPost(self): 17 18 """POST the flag view: actually flag the view (nice for XHR)""" 18 self.createSomeComments() 19 comments = self.createSomeComments() 20 pk = comments[0].pk 19 21 self.client.login(username="normaluser", password="normaluser") 20 response = self.client.post("/flag/ 1/")21 self.assertEqual(response["Location"], "http://testserver/flagged/?c= 1")22 c = Comment.objects.get(pk= 1)22 response = self.client.post("/flag/%d/" % pk) 23 self.assertEqual(response["Location"], "http://testserver/flagged/?c=%d" % pk) 24 c = Comment.objects.get(pk=pk) 23 25 self.assertEqual(c.flags.filter(flag=CommentFlag.SUGGEST_REMOVAL).count(), 1) 24 26 return c 25 27 26 28 def testFlagPostTwice(self): 27 29 """Users don't get to flag comments more than once.""" 28 30 c = self.testFlagPost() 29 self.client.post("/flag/ 1/")30 self.client.post("/flag/ 1/")31 self.client.post("/flag/%d/" % c.pk) 32 self.client.post("/flag/%d/" % c.pk) 31 33 self.assertEqual(c.flags.filter(flag=CommentFlag.SUGGEST_REMOVAL).count(), 1) 32 34 33 35 def testFlagAnon(self): 34 36 """GET/POST the flag view while not logged in: redirect to log in.""" 35 self.createSomeComments() 36 response = self.client.get("/flag/1/") 37 self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/flag/1/") 38 response = self.client.post("/flag/1/") 39 self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/flag/1/") 37 comments = self.createSomeComments() 38 pk = comments[0].pk 39 response = self.client.get("/flag/%d/" % pk) 40 self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/flag/%d/" % pk) 41 response = self.client.post("/flag/%d/" % pk) 42 self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/flag/%d/" % pk) 40 43 41 44 def testFlaggedView(self): 42 self.createSomeComments() 43 response = self.client.get("/flagged/", data={"c":1}) 45 comments = self.createSomeComments() 46 pk = comments[0].pk 47 response = self.client.get("/flagged/", data={"c":pk}) 44 48 self.assertTemplateUsed(response, "comments/flagged.html") 45 49 46 50 def testFlagSignals(self): … … 70 74 71 75 def testDeletePermissions(self): 72 76 """The delete view should only be accessible to 'moderators'""" 73 self.createSomeComments() 77 comments = self.createSomeComments() 78 pk = comments[0].pk 74 79 self.client.login(username="normaluser", password="normaluser") 75 response = self.client.get("/delete/ 1/")76 self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/delete/ 1/")80 response = self.client.get("/delete/%d/" % pk) 81 self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/delete/%d/" % pk) 77 82 78 83 makeModerator("normaluser") 79 response = self.client.get("/delete/ 1/")84 response = self.client.get("/delete/%d/" % pk) 80 85 self.assertEqual(response.status_code, 200) 81 86 82 87 def testDeletePost(self): 83 88 """POSTing the delete view should mark the comment as removed""" 84 self.createSomeComments() 89 comments = self.createSomeComments() 90 pk = comments[0].pk 85 91 makeModerator("normaluser") 86 92 self.client.login(username="normaluser", password="normaluser") 87 response = self.client.post("/delete/ 1/")88 self.assertEqual(response["Location"], "http://testserver/deleted/?c= 1")89 c = Comment.objects.get(pk= 1)93 response = self.client.post("/delete/%d/" % pk) 94 self.assertEqual(response["Location"], "http://testserver/deleted/?c=%d" % pk) 95 c = Comment.objects.get(pk=pk) 90 96 self.failUnless(c.is_removed) 91 97 self.assertEqual(c.flags.filter(flag=CommentFlag.MODERATOR_DELETION, user__username="normaluser").count(), 1) 92 98 … … 103 109 self.assertEqual(received_signals, [signals.comment_was_flagged]) 104 110 105 111 def testDeletedView(self): 106 self.createSomeComments() 107 response = self.client.get("/deleted/", data={"c":1}) 112 comments = self.createSomeComments() 113 pk = comments[0].pk 114 response = self.client.get("/deleted/", data={"c":pk}) 108 115 self.assertTemplateUsed(response, "comments/deleted.html") 109 116 110 117 class ApproveViewTests(CommentTestCase): 111 118 112 119 def testApprovePermissions(self): 113 120 """The delete view should only be accessible to 'moderators'""" 114 self.createSomeComments() 121 comments = self.createSomeComments() 122 pk = comments[0].pk 115 123 self.client.login(username="normaluser", password="normaluser") 116 response = self.client.get("/approve/ 1/")117 self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/approve/ 1/")124 response = self.client.get("/approve/%d/" % pk) 125 self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/approve/%d/" % pk) 118 126 119 127 makeModerator("normaluser") 120 response = self.client.get("/approve/ 1/")128 response = self.client.get("/approve/%d/" % pk) 121 129 self.assertEqual(response.status_code, 200) 122 130 123 131 def testApprovePost(self): … … 127 135 128 136 makeModerator("normaluser") 129 137 self.client.login(username="normaluser", password="normaluser") 130 response = self.client.post("/approve/ 1/")131 self.assertEqual(response["Location"], "http://testserver/approved/?c= 1")132 c = Comment.objects.get(pk= 1)138 response = self.client.post("/approve/%d/" % c1.pk) 139 self.assertEqual(response["Location"], "http://testserver/approved/?c=%d" % c1.pk) 140 c = Comment.objects.get(pk=c1.pk) 133 141 self.failUnless(c.is_public) 134 142 self.assertEqual(c.flags.filter(flag=CommentFlag.MODERATOR_APPROVAL, user__username="normaluser").count(), 1) 135 143 … … 146 154 self.assertEqual(received_signals, [signals.comment_was_flagged]) 147 155 148 156 def testApprovedView(self): 149 self.createSomeComments() 150 response = self.client.get("/approved/", data={"c":1}) 157 comments = self.createSomeComments() 158 pk = comments[0].pk 159 response = self.client.get("/approved/", data={"c":pk}) 151 160 self.assertTemplateUsed(response, "comments/approved.html") 152 161 153 162 -
tests/regressiontests/comment_tests/tests/comment_view_tests.py
1 import re 1 2 from django.conf import settings 2 3 from django.contrib.auth.models import User 3 4 from django.contrib.comments import signals … … 5 6 from regressiontests.comment_tests.models import Article 6 7 from regressiontests.comment_tests.tests import CommentTestCase 7 8 9 post_redirect_re = re.compile(r'^http://testserver/posted/\?c=(?P<pk>\d+$)') 10 8 11 class CommentViewTests(CommentTestCase): 9 12 10 13 def testPostCommentHTTPMethods(self): … … 181 184 a = Article.objects.get(pk=1) 182 185 data = self.getValidData(a) 183 186 response = self.client.post("/post/", data) 184 self.assertEqual(response["Location"], "http://testserver/posted/?c=1") 185 187 location = response["Location"] 188 match = post_redirect_re.match(location) 189 self.failUnless(match != None, "Unexpected redirect location: %s" % location) 190 186 191 data["next"] = "/somewhere/else/" 187 192 data["comment"] = "This is another comment" 188 193 response = self.client.post("/post/", data) 189 self.assertEqual(response["Location"], "http://testserver/somewhere/else/?c=2") 194 location = response["Location"] 195 match = re.search(r"^http://testserver/somewhere/else/\?c=\d+$", location) 196 self.failUnless(match != None, "Unexpected redirect location: %s" % location) 190 197 191 198 def testCommentDoneView(self): 192 199 a = Article.objects.get(pk=1) 193 200 data = self.getValidData(a) 194 201 response = self.client.post("/post/", data) 195 response = self.client.get("/posted/", {'c':1}) 202 location = response["Location"] 203 match = post_redirect_re.match(location) 204 self.failUnless(match != None, "Unexpected redirect location: %s" % location) 205 pk = int(match.group('pk')) 206 response = self.client.get(location) 196 207 self.assertTemplateUsed(response, "comments/posted.html") 197 self.assertEqual(response.context[0]["comment"], Comment.objects.get(pk= 1))208 self.assertEqual(response.context[0]["comment"], Comment.objects.get(pk=pk)) 198 209