Ticket #8138: test_in_transactions.diff

File test_in_transactions.diff, 14.2 KB (added by lukeplant, 7 years ago)

patch of test framework and fixes for tests

  • django/contrib/auth/tests/views.py

    diff -r ed4d2e6277b2 django/contrib/auth/tests/views.py
    a b  
    11
    22import re
    33from django.contrib.auth.models import User
    4 from django.test import TestCase
     4from django.test import TransactionTestCase
    55from django.core import mail
    66
    7 class PasswordResetTest(TestCase):
     7class PasswordResetTest(TransactionTestCase):
    88    fixtures = ['authtestdata.json']
    99    urls = 'django.contrib.auth.urls'
    1010   
  • django/core/management/commands/loaddata.py

    diff -r ed4d2e6277b2 django/core/management/commands/loaddata.py
    a b  
    2828
    2929        verbosity = int(options.get('verbosity', 1))
    3030        show_traceback = options.get('traceback', False)
     31        no_commit = options.get('no_commit', False)
    3132
    3233        # Keep a count of the installed objects and fixtures
    3334        fixture_count = 0
     
    4445
    4546        # Start transaction management. All fixtures are installed in a
    4647        # single transaction to ensure that all references are resolved.
    47         transaction.commit_unless_managed()
    48         transaction.enter_transaction_management()
    49         transaction.managed(True)
     48        if not no_commit:
     49            transaction.commit_unless_managed()
     50            transaction.enter_transaction_management()
     51            transaction.managed(True)
    5052
    5153        app_fixtures = [os.path.join(os.path.dirname(app.__file__), 'fixtures') for app in get_apps()]
    5254        for fixture_label in fixture_labels:
     
    133135                                (format, fixture_name, humanize(fixture_dir))
    134136
    135137
    136         # If any of the fixtures we loaded contain 0 objects, assume that an 
     138        # If any of the fixtures we loaded contain 0 objects, assume that an
    137139        # error was encountered during fixture loading.
    138140        if 0 in objects_per_fixture:
    139141            sys.stderr.write(
     
    142144            transaction.rollback()
    143145            transaction.leave_transaction_management()
    144146            return
    145            
    146         # If we found even one object in a fixture, we need to reset the 
     147
     148        # If we found even one object in a fixture, we need to reset the
    147149        # database sequences.
    148150        if object_count > 0:
    149151            sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
     
    152154                    print "Resetting sequences"
    153155                for line in sequence_sql:
    154156                    cursor.execute(line)
    155            
    156         transaction.commit()
    157         transaction.leave_transaction_management()
     157
     158        if not no_commit:
     159            transaction.commit()
     160            transaction.leave_transaction_management()
    158161
    159162        if object_count == 0:
    160163            if verbosity > 1:
     
    162165        else:
    163166            if verbosity > 0:
    164167                print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)
    165                
     168
    166169        # Close the DB connection. This is required as a workaround for an
    167170        # edge case in MySQL: if the same connection is used to
    168171        # create tables, load data, and query, the query can return
    169172        # incorrect results. See Django #7572, MySQL #37735.
    170         connection.close()
     173        if not no_commit:
     174            connection.close()
  • django/test/__init__.py

    diff -r ed4d2e6277b2 django/test/__init__.py
    a b  
    33"""
    44
    55from django.test.client import Client
    6 from django.test.testcases import TestCase
     6from django.test.testcases import TestCase, TransactionTestCase
  • django/test/testcases.py

    diff -r ed4d2e6277b2 django/test/testcases.py
    a b  
    5555        """Tries to do a 'xml-comparision' of want and got.  Plain string
    5656        comparision doesn't always work because, for example, attribute
    5757        ordering should not be important.
    58        
     58
    5959        Based on http://codespeak.net/svn/lxml/trunk/src/lxml/doctestcompare.py
    6060        """
    6161        _norm_whitespace_re = re.compile(r'[ \t\n][ \t\n]+')
     
    102102            wrapper = '<root>%s</root>'
    103103            want = wrapper % want
    104104            got = wrapper % got
    105            
     105
    106106        # Parse the want and got strings, and compare the parsings.
    107107        try:
    108108            want_root = parseString(want).firstChild
     
    169169        # side effects on other tests.
    170170        transaction.rollback_unless_managed()
    171171
    172 class TestCase(unittest.TestCase):
     172    def run(self, test, compileflags=None, out=None, clear_globs=True):
     173        """
     174        Wraps the parent run() and encloses it in a transaction.
     175        """
     176        tests_use_transactions = test.docstring.strip().startswith('# TESTS USE TRANSACTIONS')
     177        if not tests_use_transactions:
     178            transaction.enter_transaction_management()
     179            transaction.managed(True)
     180        result = doctest.DocTestRunner.run(self, test, compileflags, out, clear_globs)
     181        if not tests_use_transactions:
     182            transaction.rollback()
     183            transaction.leave_transaction_management()
     184        return result
     185
     186class TransactionTestCase(unittest.TestCase):
    173187    def _pre_setup(self):
    174188        """Performs any pre-test setup. This includes:
    175189
    176190            * Flushing the database.
    177             * If the Test Case class has a 'fixtures' member, installing the 
     191            * If the Test Case class has a 'fixtures' member, installing the
    178192              named fixtures.
    179193            * If the Test Case class has a 'urls' member, replace the
    180194              ROOT_URLCONF with it.
    181195            * Clearing the mail test outbox.
    182196        """
     197        self._fixture_setup()
     198        self._urlconf_setup()
     199        mail.outbox = []
     200
     201    def _fixture_setup(self):
    183202        call_command('flush', verbosity=0, interactive=False)
    184203        if hasattr(self, 'fixtures'):
    185204            # We have to use this slightly awkward syntax due to the fact
    186205            # that we're using *args and **kwargs together.
    187206            call_command('loaddata', *self.fixtures, **{'verbosity': 0})
     207
     208    def _urlconf_setup(self):
    188209        if hasattr(self, 'urls'):
    189210            self._old_root_urlconf = settings.ROOT_URLCONF
    190211            settings.ROOT_URLCONF = self.urls
    191212            clear_url_caches()
    192         mail.outbox = []
    193213
    194214    def __call__(self, result=None):
    195215        """
     
    206226            import sys
    207227            result.addError(self, sys.exc_info())
    208228            return
    209         super(TestCase, self).__call__(result)
     229        super(TransactionTestCase, self).__call__(result)
    210230        try:
    211231            self._post_teardown()
    212232        except (KeyboardInterrupt, SystemExit):
     
    221241
    222242            * Putting back the original ROOT_URLCONF if it was changed.
    223243        """
     244        self._fixture_teardown()
     245        self._urlconf_teardown()
     246
     247    def _fixture_teardown(self):
     248        pass
     249
     250    def _urlconf_teardown(self):
    224251        if hasattr(self, '_old_root_urlconf'):
    225252            settings.ROOT_URLCONF = self._old_root_urlconf
    226253            clear_url_caches()
     
    354381        self.failIf(template_name in template_names,
    355382            (u"Template '%s' was used unexpectedly in rendering the"
    356383             u" response") % template_name)
     384
     385class TestCase(TransactionTestCase):
     386    """
     387    Does basically the same as TransactionTestCase, but surrounds every test
     388    with a transaction. You have to use TransactionTestCase, if you need
     389    transaction management inside a test.
     390    """
     391    def _fixture_setup(self):
     392        transaction.enter_transaction_management()
     393        transaction.managed(True)
     394
     395        if hasattr(self, 'fixtures'):
     396            call_command('loaddata', *self.fixtures, **{
     397                                                        'verbosity': 0,
     398                                                        'no_commit': True
     399                                                        })
     400
     401    def _fixture_teardown(self):
     402        transaction.rollback()
     403        transaction.leave_transaction_management()
  • tests/modeltests/fixtures/models.py

    diff -r ed4d2e6277b2 tests/modeltests/fixtures/models.py
    a b  
    2222        ordering = ('-pub_date', 'headline')
    2323
    2424__test__ = {'API_TESTS': """
     25# TESTS USE TRANSACTIONS
    2526>>> from django.core import management
    2627>>> from django.db.models import get_app
    2728
     
    9293    def testClassFixtures(self):
    9394        "Check that test case has installed 4 fixture objects"
    9495        self.assertEqual(Article.objects.count(), 4)
    95         self.assertEquals(str(Article.objects.all()), "[<Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]")
     96        self.assertEquals(str(Article.objects.order_by('headline')), "[<Article: Copyright is fine the way it is>, <Article: Django conquers world!>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]")
  • tests/modeltests/test_client/models.py

    diff -r ed4d2e6277b2 tests/modeltests/test_client/models.py
    a b  
    2020rather than the HTML rendered to the end-user.
    2121
    2222"""
    23 from django.test import Client, TestCase
     23from django.test import Client, TransactionTestCase
    2424from django.core import mail
    2525
    26 class ClientTest(TestCase):
     26class ClientTest(TransactionTestCase):
    2727    fixtures = ['testdata.json']
    2828
    2929    def test_get_view(self):
  • tests/regressiontests/admin_views/tests.py

    diff -r ed4d2e6277b2 tests/regressiontests/admin_views/tests.py
    a b  
    11
    2 from django.test import TestCase
     2from django.test import TestCase, TransactionTestCase
    33from django.contrib.auth.models import User, Permission
    44from django.contrib.contenttypes.models import ContentType
    55from django.contrib.admin.models import LogEntry
     
    1515    ct = ContentType.objects.get_for_model(Model)
    1616    return Permission.objects.get(content_type=ct,codename=perm)
    1717
    18 class AdminViewPermissionsTest(TestCase):
     18class AdminViewPermissionsTest(TransactionTestCase):
    1919    """Tests for Admin Views Permissions."""
    2020   
    2121    fixtures = ['admin-views-users.xml']
  • tests/regressiontests/test_client_regress/models.py

    diff -r ed4d2e6277b2 tests/regressiontests/test_client_regress/models.py
    a b  
    22Regression tests for the Test Client, especially the customized assertions.
    33"""
    44
    5 from django.test import Client, TestCase
     5from django.test import Client, TestCase, TransactionTestCase
    66from django.core.urlresolvers import reverse
    77from django.core.exceptions import SuspiciousOperation
    88
     
    239239        except AssertionError, e:
    240240            self.assertEqual(str(e), "The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )")
    241241
    242 class LoginTests(TestCase):
     242class LoginTests(TransactionTestCase):
    243243    fixtures = ['testdata']
    244244
    245245    def test_login_different_client(self):
     
    283283        self.assertEqual(response.status_code, 200)
    284284        self.assertEqual(response.content, 'Hi, Arthur')
    285285
    286 class ExceptionTests(TestCase):
     286class ExceptionTests(TransactionTestCase):
    287287    fixtures = ['testdata.json']
    288288
    289289    def test_exception_cleared(self):
  • tests/regressiontests/views/tests/defaults.py

    diff -r ed4d2e6277b2 tests/regressiontests/views/tests/defaults.py
    a b  
    11from os import path
    22
    33from django.conf import settings
    4 from django.test import TestCase
     4from django.test import TransactionTestCase
    55from django.contrib.contenttypes.models import ContentType
    66
    77from regressiontests.views.models import Author, Article
    88
    9 class DefaultsTests(TestCase):
     9class DefaultsTests(TransactionTestCase):
    1010    """Test django views in django/views/defaults.py"""
    1111    fixtures = ['testdata.json']
    1212
  • tests/regressiontests/views/tests/generic/create_update.py

    diff -r ed4d2e6277b2 tests/regressiontests/views/tests/generic/create_update.py
    a b  
    11import datetime
    22
    3 from django.test import TestCase
     3from django.test import TransactionTestCase
    44from django.core.exceptions import ImproperlyConfigured
    55from regressiontests.views.models import Article, UrlArticle
    66
    7 class CreateObjectTest(TestCase):
     7class CreateObjectTest(TransactionTestCase):
    88
    99    fixtures = ['testdata.json']
    1010
     
    6565            '/views/create_update/view/article/some-other-slug/',
    6666            target_status_code=404)
    6767
    68 class UpdateDeleteObjectTest(TestCase):
     68class UpdateDeleteObjectTest(TransactionTestCase):
    6969
    7070    fixtures = ['testdata.json']
    7171
     
    111111        else:
    112112            self.fail('Object was not deleted.')
    113113
    114 class PostSaveRedirectTests(TestCase):
     114class PostSaveRedirectTests(TransactionTestCase):
    115115    """
    116116    Verifies that the views redirect to the correct locations depending on
    117117    if a post_save_redirect was passed and a get_absolute_url method exists
  • tests/regressiontests/views/tests/i18n.py

    diff -r ed4d2e6277b2 tests/regressiontests/views/tests/i18n.py
    a b  
    22import gettext
    33
    44from django.conf import settings
    5 from django.test import TestCase
     5from django.test import TransactionTestCase
    66from django.utils.translation import activate
    77
    88from regressiontests.views.urls import locale_dir
    99
    10 class I18NTests(TestCase):
     10class I18NTests(TransactionTestCase):
    1111    """ Tests django views in django/views/i18n.py """
    1212
    1313    def test_setlang(self):
Back to Top