Модульные тесты терпят неудачу после обновления Django

Я пытаюсь перенести проект Django с версии 1.8 на 1.11. Почти все, кажется, работает нормально, кроме модульных тестов. У нас есть базовый тестовый класс, унаследованный от Django TestCase с миксином Tastypie. Базовый класс имеет некоторый код в setUp(), подобный этому

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
        )

И специальные тесты приложения будут наследовать базовый тест и делать что-то вроде

class TheAPITest(BaseApiTest):
    def setUp(self):
        super().setUp()
        # more setup goes here

Итак, под Django 1.8.x это работает нормально. Но под 1.11.x все это выдает ошибку на User.objects.create_superuser() line.

django.db.utils.InterfaceError: connection already closed

Я просматривал примечания к выпуску, но слишком много всего произошло между версиями 1.8 и 1.11. Есть ли что-то простое, что мне не хватает?


person Mad Wombat    schedule 04.08.2017    source источник
comment
Несколько вопросов, какую БД вы используете? версия питона? И образец проекта, который мы можем использовать для тестирования?   -  person Tarun Lalwani    schedule 07.08.2017
comment
Постгрес 9.5 и питон 3.5.х   -  person Mad Wombat    schedule 07.08.2017
comment
Это коммерческий проект, поэтому я не вправе делиться первоисточником. Не уверен, что смогу вырезать образец проекта из кодовой базы.   -  person Mad Wombat    schedule 07.08.2017
comment
Какой образец шаблона, который вы можете дать, я могу использовать для воспроизведения проблемы?   -  person Tarun Lalwani    schedule 07.08.2017
comment
Не нужно помещать много кода, наименьший возможный шаблон, который приведет к ошибке на вашем конце. Потому что иначе было бы трудно разобраться. Может быть из-за чего-то, что вы используете в конфигурации вашего приложения или в общем. Так что без образца шаблона было бы трудно разобраться   -  person Tarun Lalwani    schedule 07.08.2017
comment
Я попытаюсь настроить минимальный пример, но не могу обещать.   -  person Mad Wombat    schedule 07.08.2017
comment
Не беспокойтесь, даже я не могу обещать решения. Просто пытаюсь помочь   -  person Tarun Lalwani    schedule 07.08.2017
comment
1. Попробуйте docs.djangoproject.com/en/1.11/topics/ testing/tools/ вместо TestCase 2. Попробуйте добавить методы удаления: groups.google.com/forum/#!topic/django-users/MDRcg4Fur98   -  person Michael    schedule 07.08.2017
comment
Я попробовал это с TransactionTestCase вместо тестового примера. Тот же результат.   -  person Mad Wombat    schedule 07.08.2017
comment
И в базовом классе есть метод tearDown(), так что он тоже не работает.   -  person Mad Wombat    schedule 07.08.2017
comment
Кажется, я наконец добрался до сути этого. Опубликую ответ, когда я получу каждый тест для работы. TL; DR 1) если какой-то тест не проходит достаточно сильно, база данных закрывается и больше не открывается. И каждый тест после этого получает ошибку, которую я опубликовал выше. 2) Django 1.11 намного строже относится к созданию экземпляров модели, чем 1.8. 1.8 позволяет вам передавать аргументы в create(), которые не соответствуют каким-либо полям, и, по-видимому, в наших тестах у нас было много таких.   -  person Mad Wombat    schedule 07.08.2017
comment
Я не уверен, помогает ли это. Не могли бы вы взглянуть на этот docs.djangoproject. com/en/1.9/topics/testing/tools/   -  person Hardyanto Putra Antoni    schedule 11.08.2017
comment
Можете ли вы поделиться своим журналом ошибок PostGre и Django, если таковые имеются. Это поможет правильно диагностировать проблему.   -  person Jaffer Wilson    schedule 11.08.2017


Ответы (2)


Я обнаружил несколько проблем с покрытием моего модульного теста, но, чтобы ответить на вопрос, который я разместил, две отдельные проблемы вызывали ошибки, которые я описал.

Django 1.11 строже относится к созданию экземпляра модели, и у нас был некоторый устаревший тестовый код, который не был обновлен до новой структуры модели. Например, если вы возьмете модель пользователя по умолчанию, в Django 1.8 вы можете сделать

from django.contrib.auth.models import User    
User.objects.create(username="something", password="something", something="something")

Но в Django 1.11 это вызовет исключение "TypeError: 'something' is an invalid keyword argument for this function".

И вторая проблема заключается в том, что Django TestCase оборачивает тестовые случаи в два отдельных атомарных блока. Это помогает отделить настройку на уровне класса от настройки на уровне экземпляра, но также создает небольшую проблему. Если тест завершается сбоем из-за ошибки базы данных, вы никогда не увидите ошибку, потому что это происходит на уровне теста atomic, а не на уровне класса atomic. Атомарный уровень теста терпит неудачу, и соединение с базой данных разрывается. После этого каждый тест будет терпеть неудачу с точной ошибкой django.db.utils.InterfaceError: connection already closed, которую я видел. Переход с TestCase на TransactionTestCase привел к тому, что многие из этих проблем стали видны непосредственно в выводе теста.

person Mad Wombat    schedule 29.08.2017
comment
Будьте здоровы!! Я боролся с этим весь день. - person man2xxl; 17.07.2020
comment
Переход на TransactionTestCase решил проблему для меня - спасибо! - person Patrick; 12.12.2020

Может быть полезно иметь трассировку ошибок. Но на данный момент в коде я вижу эту ошибку:

   self.user = User.objects.create_superuser(
                self.username,
                self.username, **this should be self.email**
                self.password
            )
person wololoooo    schedule 14.08.2017