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