Проблемы с использованием пользовательской модели в модульных тестах django - PullRequest
20 голосов
/ 15 мая 2010

У меня есть следующий тестовый пример 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 перед каждым тестом и обнаруживает, что он уже существует в базе данных. Как заставить его правильно очищаться после каждого теста, чтобы последующие тесты работали правильно?

Ответы [ 3 ]

28 голосов
/ 15 мая 2010
Методы

setUp и tearDown на тестах юнитов вызываются до и после каждого теста.Определите метод 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 ON DELETE CASCADE - другими словами, любые объекты, которые имеют внешние ключи, указывающие на объект, который будет удален будет удален вместе с ним.

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

9 голосов
/ 29 декабря 2012

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

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

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

2 голосов
/ 15 мая 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...