#33906: TestCase inconsistent behavior on Db integrity error
-------------------------------------+-------------------------------------
     Reporter:  an-mile              |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Testing framework    |                  Version:  4.0
     Severity:  Normal               |               Resolution:
     Keywords:  testsuite            |             Triage Stage:
  integrityError bug inconsistent    |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by an-mile:

Old description:

> Hello! I'm filing my first Django bug and hopefully it is meaningful:
>
> When a db integrity error occurs in some test, the exception is captured
> by the test suite and following code in the test is executed. This is
> inconsistent with any other exception that might arise from test code
> execution.
> It might be similar to the closed ticket
> https://code.djangoproject.com/ticket/14223
>
> models.py:
>
> {{{
>
> from django.db import models
>
> # inspired by https://code.djangoproject.com/ticket/14223
>
> class Reporter(models.Model):
>     first_name = models.CharField(max_length=30)
>     last_name = models.CharField(max_length=30)
>     email = models.EmailField(null=True)
>
>     def __unicode__(self):
>         return u"%s %s" % (self.first_name, self.last_name)
>
> class Article(models.Model):
>     reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE,)
>     headline = models.CharField(max_length=100)
>
> }}}
>
> tests.py:
>
> {{{
> from django.test import TestCase
>
> from mod.models import Reporter, Article
>

> class DatabasePsycopgTest(TestCase):
>
>     def test_db_integrity_error_handling(self):
>         objs = [Article(reporter_id=123, headline='Hello DB integrity')]
>         # NammeErrorWouldRaiseHere
>         Article.objects.bulk_create(objs)  # DB Integrity Error
> captured...
>        print('Hello Dear Django Coders!')
>         self.assertEqual(1, 2)
> }}}
>
> Here we get following traceback:
> {{{
> Traceback (most recent call last):
>   File "/..../python3.9/site-packages/django/test/testcases.py", line
> 299, in _setup_and_call
>     self._post_teardown()
>   File "/..../python3.9/site-packages/django/test/testcases.py", line
> 1199, in _post_teardown
>     self._fixture_teardown()
>   File "/..../python3.9/site-packages/django/test/testcases.py", line
> 1461, in _fixture_teardown
>     connections[db_name].check_constraints()
>   File "/..../python3.9/site-
> packages/django/db/backends/sqlite3/base.py", line 383, in
> check_constraints
>     raise IntegrityError(
> django.db.utils.IntegrityError: The row in table 'mod_article' with
> primary key '1' has an invalid foreign key: mod_article.reporter_id
> contains a value '123' that does not have a corresponding value in
> mod_reporter.id.
>
>   File "/..../codelab/dabase/mod/tests.py", line 12, in
> test_db_integrity_error_handling
>     self.assertEqual(1, 2)
> AssertionError: 1 != 2
> }}}
> But when uncommenting the "NammeErrorWouldRaiseHere" ,  "Hello Dear
> Django Coders!'"  is not printed, nor the last "AssertionError" is not
> executed. This seams confusing and inconsistent behavior.
>
> It appears on SQLite as well as with PsycoPg / PG. Furthermore, the
> exception can not be captured within the Code with a regular try-except.
> Following modification of the test will not print "Hello" :
> {{{
>         try:
>             Article.objects.bulk_create(objs)
>         except Exception:
>             print('Hello')
> }}}

New description:

 Hello! I'm filing my first Django bug and hopefully it is meaningful:

 When a db integrity error occurs in some test, the exception is captured
 by the test suite and following code in the test is executed. This seems
 inconsistent with any other exception that might arise from test code
 execution.
 It might be similar to the closed ticket
 https://code.djangoproject.com/ticket/14223

 models.py:

 {{{

 from django.db import models

 # inspired by https://code.djangoproject.com/ticket/14223

 class Reporter(models.Model):
     first_name = models.CharField(max_length=30)
     last_name = models.CharField(max_length=30)
     email = models.EmailField(null=True)

     def __unicode__(self):
         return u"%s %s" % (self.first_name, self.last_name)

 class Article(models.Model):
     reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE,)
     headline = models.CharField(max_length=100)

 }}}

 tests.py:

 {{{
 from django.test import TestCase

 from mod.models import Reporter, Article


 class DatabasePsycopgTest(TestCase):

     def test_db_integrity_error_handling(self):
         objs = [Article(reporter_id=123, headline='Hello DB integrity')]
         # NammeErrorWouldRaiseHere
         Article.objects.bulk_create(objs)  # DB Integrity Error
 captured...
         print('Hello Dear Django Coders!')
         self.assertEqual(1, 2)
 }}}

 Here we get following traceback:
 {{{
 Traceback (most recent call last):
   File "/..../python3.9/site-packages/django/test/testcases.py", line 299,
 in _setup_and_call
     self._post_teardown()
   File "/..../python3.9/site-packages/django/test/testcases.py", line
 1199, in _post_teardown
     self._fixture_teardown()
   File "/..../python3.9/site-packages/django/test/testcases.py", line
 1461, in _fixture_teardown
     connections[db_name].check_constraints()
   File "/..../python3.9/site-packages/django/db/backends/sqlite3/base.py",
 line 383, in check_constraints
     raise IntegrityError(
 django.db.utils.IntegrityError: The row in table 'mod_article' with
 primary key '1' has an invalid foreign key: mod_article.reporter_id
 contains a value '123' that does not have a corresponding value in
 mod_reporter.id.

   File "/..../codelab/dabase/mod/tests.py", line 12, in
 test_db_integrity_error_handling
     self.assertEqual(1, 2)
 AssertionError: 1 != 2
 }}}
 But when uncommenting the "NammeErrorWouldRaiseHere" ,  "Hello Dear Django
 Coders!'"  is not printed, nor is the last "AssertionError" executed. This
 seems confusing and inconsistent behavior.

 It appears on SQLite as well as with PsycoPg / PG. Furthermore, the
 exception can not be captured within the Code with a regular try-except.
 Following modification of the test will not print "Hello" :
 {{{
         try:
             Article.objects.bulk_create(objs)
         except Exception:
             print('Hello')
 }}}

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33906#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 view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701827ca2abd0-0ea80ca5-3bb3-44ad-8773-ef0cd2fc176a-000000%40eu-central-1.amazonses.com.

Reply via email to