Подтвердить что ты не робот

Проблемы с использованием модели пользователя в модульных тестах django

У меня есть следующий тестовый пример django, который дает мне ошибки:

class MyTesting(unittest.TestCase):
    def setUp(self):
        self.u1 = User.objects.create(username='user1')
        self.up1 = UserProfile.objects.create(user=self.u1)

    def testA(self):
        ...

    def testB(self):
        ...

Когда я запускаю свои тесты, testA пройдет успешно, но до начала testB я получаю следующую ошибку:

IntegrityError: column username is not unique

Это ясно, что он пытается создать self.u1 перед каждым тестовым случаем и обнаружив, что он уже существует в базе данных. Как мне заставить его правильно очищать после каждого теста, чтобы последующие случаи выполнялись правильно?

4b9b3361

Ответ 1

setUp и tearDown методы на Unittests вызывается до и после каждого теста. Определите tearDown метод, который удаляет созданного пользователя.

class MyTesting(unittest.TestCase):
    def setUp(self):
        self.u1 = User.objects.create(username='user1')
        self.up1 = UserProfile.objects.create(user=self.u1)

    def testA(self):
        ...

    def tearDown(self):
        self.up1.delete()
        self.u1.delete()

Я также посоветую создавать профили пользователей, используя post_save, если вы действительно не хотите создавать профиль пользователя вручную для каждого пользователя.

Последующее наблюдение при удалении комментария:

От Django docs:

Когда Django удаляет объект, он эмулирует поведение SQL ограничение УДАЛИТЬ КАСКАД - в другими словами, любые объекты, которые внешние ключи, указывающие на объект, чтобы быть удалена, будет удалена вместе с он.

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

Ответ 2

Если вы хотите, чтобы django автоматически удалял тестовую базу данных после запуска каждого теста, вы должны расширить django.test.TestCase, NOT django.utils.unittest.TestCase (как вы делаете в настоящее время).

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

Смотрите раздел ПРЕДУПРЕЖДЕНИЕ в "Письменных тестах" Django Docs.

Ответ 3

Точно, setUp существует для самой цели для запуска один раз перед каждым тестовым случаем.

Обратный метод, который запускается один раз после каждого тестового примера, называется tearDown: то, где вы удаляете self.u1 и т.д. (предположительно, просто вызывая self.u1.delete(), если у вас нет дополнительных специализированных требований по очистке в добавление к простому удалению объекта).