I am trying to bring a Django project from version 1.8 to 1.11. Pretty much everything seems to work fine except unit tests. We have a base test class inheriting from Django TestCase with a Tastypie mixin. The base class has some code in the setUp() like this
class BaseApiTest(ResourceTestCaseMixin, django.test.TestCase):
def setUp(self):
super().setUp()
self.username = "secret_user"
self.password = "sekret"
self.email = "[email protected]"
self.first_name = "FirstName"
self.last_name = "LastName"
self.user = User.objects.create_superuser(
self.username,
self.username,
self.password
)
And the app specific tests would inherit the base test and do something like
class TheAPITest(BaseApiTest):
def setUp(self):
super().setUp()
# more setup goes here
So, under Django 1.8.x this works fine. But under 1.11.x all of these give me an error on the User.objects.create_superuser() line
.
django.db.utils.InterfaceError: connection already closed
I have been going through the release notes, but there is just too much stuff that has happened between 1.8 and 1.11. Is there something simple that I am missing?
I have uncovered multiple issues with my unit test coverage, but to answer the question I posted, two separate issues were causing the errors I described.
Django 1.11 is stricter about its model instance creation and we had some legacy test code that was not updated to new model structure. For example, if you take the default User model, in Django 1.8 you can do
from django.contrib.auth.models import User
User.objects.create(username="something", password="something", something="something")
But in Django 1.11 it will raise an exception "TypeError: 'something' is an invalid keyword argument for this function"
.
And the second issue is that Django TestCase wraps test cases in two separate atomic blocks. This helps with keeping class level setup separate from instance level setup, but it also introduces a subtle problem. If a test crashes with a database error you never see the error because it happens in the test level atomic and not in the class level atomic. The test level atomic fails and database connection gets dropped. After that every test is going to fail with the exact django.db.utils.InterfaceError: connection already closed
error I was seeing. Switching from TestCase to TransactionTestCase caused a lot of these problems to be exposed directly in the test output.
It may be useful to have the error trace. But for the moment in the code I see this error:
self.user = User.objects.create_superuser(
self.username,
self.username, **this should be self.email**
self.password
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With