#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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
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