#28400: TransactionTestCase will truncate data created from data migration
-------------------------------------+-------------------------------------
     Reporter:  Jared Mackey         |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Testing framework    |                  Version:  1.11
     Severity:  Normal               |               Resolution:
     Keywords:  tests,data-          |             Triage Stage:
  migrations                         |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Jared Mackey:

Old description:

> Data migrations that create data in the database do not persist after
> running tests that inherit from `TransactionTestCase`. The first test
> that runs on the database works as expected but subsequent tests do not.
>
> Here is an example migration:
>
> {{{
> def add_group_permissions(apps, schema_editor):
>     for app_config in apps.get_app_configs():
>         app_config.models_module = True
>         create_permissions(app_config, verbosity=0)
>         app_config.models_module = None
>
>     Group = apps.get_model('auth', 'Group')
>     Permission = apps.get_model('auth', 'Permission')
>
>     group, _ = Group.objects.get_or_create(name='demo_group')
>     group.permissions.clear()
>     permission = Permission.objects.get(codename='existing_permission')
>     group.permissions.add(permission)
>

> class Migration(migrations.Migration):
>
>     dependencies = [ ]
>
>     operations = [
>         migrations.RunPython(add_group_permissions,
> reverse_code=migrations.RunPython.noop),
>         migrations.RunPython(lambda apps, schema_editor:
> ContentType.objects.clear_cache()),   # hack to get the ContentType cache
> to clear
>     ]
> }}}
>
> Here is a test case that will prove that the second test to run will fail
> with `django.contrib.auth.models.DoesNotExist: Group matching query does
> not exist.`
>
> {{{
> class TestGroupsExist(TransactionTestCase):
>     """ One of these tests will fail. Which one depends on which one the
> test runner runs first. The second one to run will fail. """
>     def test_group_exists_1(self):
> self.assertIsNotNone(Group.objects.get_by_natural_key('demo_group'))
>
>     def test_group_exists_2(self):
> self.assertIsNotNone(Group.objects.get_by_natural_key('demo_group'))
> }}}
>
> The following log is found after the first test is ran.
>
> `TRUNCATE ... "auth_group_permissions", "auth_group", ...;; args=None`
>
> A possible solution to this is to re-run data only migrations after
> truncating the tables.

New description:

 Data migrations that create data in the database do not persist after
 running tests that inherit from `TransactionTestCase`. The first test that
 runs on the database works as expected but subsequent tests do not. I am
 filling as a bug as I would expect that data created before tests are ran
 would persist a transaction rollback during the test cases. A possible
 solution to this is to re-run data only migrations after truncating the
 tables.

 Here is an example migration:

 {{{
 def add_group_permissions(apps, schema_editor):
     for app_config in apps.get_app_configs():
         app_config.models_module = True
         create_permissions(app_config, verbosity=0)
         app_config.models_module = None

     Group = apps.get_model('auth', 'Group')
     Permission = apps.get_model('auth', 'Permission')

     group, _ = Group.objects.get_or_create(name='demo_group')
     group.permissions.clear()
     permission = Permission.objects.get(codename='existing_permission')
     group.permissions.add(permission)


 class Migration(migrations.Migration):

     dependencies = [ ]

     operations = [
         migrations.RunPython(add_group_permissions,
 reverse_code=migrations.RunPython.noop),
         migrations.RunPython(lambda apps, schema_editor:
 ContentType.objects.clear_cache()),   # hack to get the ContentType cache
 to clear
     ]
 }}}

 Here is a test case that will prove that the second test to run will fail
 with `django.contrib.auth.models.DoesNotExist: Group matching query does
 not exist.`

 {{{
 class TestGroupsExist(TransactionTestCase):
     """ One of these tests will fail. Which one depends on which one the
 test runner runs first. The second one to run will fail. """
     def test_group_exists_1(self):
 self.assertIsNotNone(Group.objects.get_by_natural_key('demo_group'))

     def test_group_exists_2(self):
 self.assertIsNotNone(Group.objects.get_by_natural_key('demo_group'))
 }}}

 The following log is found after the first test is ran.

 `TRUNCATE ... "auth_group_permissions", "auth_group", ...;; args=None`

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28400#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/068.a86c064f5e7ff20c6cea5c9905ceae04%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to