0
votes

I'm almost starting to wonder if there is some limit on how many TestCases a Django app can have, so I need your help to figure out how to avoid this problem and have functional tests in my app with all of the TestCases.

My Django (v1.10.7) app has 4 fixture TestCases, which run fine. As soon as I add a 5th TestCase with fixtures, running the tests all together with

python3 ./manage.py test myapp

starts resulting in a random one of the old TestCases failing with:

ERROR: setUpClass (myapp.tests.RandomOldTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/django/db/backends/base/base.py", line 206, in _cursor
    return self.create_cursor()
  File "/usr/lib/python3/dist-packages/django/db/backends/postgresql/base.py", line 211, in create_cursor
    cursor = self.connection.cursor()
psycopg2.InterfaceError: connection already closed

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/django/test/testcases.py", line 1019, in setUpClass
    'database': db_name,
  File "/usr/lib/python3/dist-packages/django/core/management/__init__.py", line 130, in call_command
    return command.execute(*args, **defaults)
  File "/usr/lib/python3/dist-packages/django/core/management/base.py", line 345, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python3/dist-packages/django/core/management/commands/loaddata.py", line 64, in handle
    self.loaddata(fixture_labels)
  File "/usr/lib/python3/dist-packages/django/core/management/commands/loaddata.py", line 104, in loaddata
    self.load_label(fixture_label)
  File "/usr/lib/python3/dist-packages/django/core/management/commands/loaddata.py", line 167, in load_label
    obj.save(using=self.using)
  File "/usr/lib/python3/dist-packages/django/core/serializers/base.py", line 201, in save
    models.Model.save_base(self.object, using=using, raw=True, **kwargs)
  File "/usr/lib/python3/dist-packages/django/db/models/base.py", line 824, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/usr/lib/python3/dist-packages/django/db/models/base.py", line 889, in _save_table
    forced_update)
  File "/usr/lib/python3/dist-packages/django/db/models/base.py", line 939, in _do_update
    return filtered._update(values) > 0
  File "/usr/lib/python3/dist-packages/django/db/models/query.py", line 654, in _update
    return query.get_compiler(self.db).execute_sql(CURSOR)
  File "/usr/lib/python3/dist-packages/django/db/models/sql/compiler.py", line 1148, in execute_sql
    cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
  File "/usr/lib/python3/dist-packages/django/db/models/sql/compiler.py", line 833, in execute_sql
    cursor = self.connection.cursor()
  File "/usr/lib/python3/dist-packages/django/db/backends/base/base.py", line 233, in cursor
    cursor = self.make_cursor(self._cursor())
  File "/usr/lib/python3/dist-packages/django/db/backends/base/base.py", line 206, in _cursor
    return self.create_cursor()
  File "/usr/lib/python3/dist-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/lib/python3/dist-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/lib/python3/dist-packages/django/db/backends/base/base.py", line 206, in _cursor
    return self.create_cursor()
  File "/usr/lib/python3/dist-packages/django/db/backends/postgresql/base.py", line 211, in create_cursor
    cursor = self.connection.cursor()
django.db.utils.InterfaceError: Problem installing fixture '/home/lynoure/PycharmProjects/usertools2/useraccounts/fixtures/test-fixtures.json': connection already closed

It doesn't seem to matter what the new TestCase is, this happens even if I duplicate a pre-existing test with a new name.

In case it matters, this is on Debian Stable, the version of postgresql is 9.6+181, and python3-psycopg2 is 2.6.2-1.

2
It seemed tempting to 'solve' this by moving into using a TransactionTestCase for this, but then fixtures didn't get loaded in, so something would still be broken that way.Lynoure
serialized_rollback = True doesn't seem to make any difference eitherLynoure
--parallel=1 makes no difference eitherLynoure

2 Answers

1
votes

Turned out that if you have couple of

super().tearDownClass()

missing from your code, this is the kind of symptoms you get. So, if this happens to you, check that your TestCase has the tearDownClass calling the parent.

0
votes

As a workaround one can tag some of the TestCases, and then only run tests with the tag excluded:

from django.test import tag

@tag('trouble')
class TroubleTestCase(TestCase):
...

And to run:

python3 ./manage.py test myapp --exclude-tag=trouble

One has to run those tests separately afterwards:

python3 ./manage.py test myapp --tag=trouble