Тест Django с помощью фикстур выдает ForeignKeyViolation или IntegrityError
Я пытаюсь написать тестовые примеры для Django RestAPI, который у нас есть, но у меня возникла проблема с загрузкой фикстур. Все работает правильно, когда у меня только один TestCase, но когда я добавляю второй TestCase во втором приложении django, я получаю django.db.utils.IntegrityError. Моим первоначальным намерением было создать общий TestCase, в котором я устанавливаю наиболее используемые объекты в функции setUpTestData и заставляю другие тесты наследоваться от него.
То, что я пробовал:
- Использование APITestCase из rest_framework и TestCase из django
- Не используя наследование, и имея оба файла, использующие TestCase из django .
- Использование метода setUp вместо setUpTestData
- Использование call_command из django.core.management в методе setUpTestData вместо создания приспособлений в каждом классе в переменной класса
- Декларирование фикстур только в TestCase, который выполняется первым (это заставляет остальные TestCase иметь пустую БД, так что понятно, что для каждого TestCase информация создается заново)
- Изменили порядок файлов в переменной fixtures
Когда я комментирую один из тестовых файлов, другой работает, и наоборот. Когда я использовал команду call_command с verbose=2, фикстуры в первом файле выполняются отлично, и ломается только при попытке установить первую фикстуру из второго файла, с ошибкой:
django.db.utils.IntegrityError: Problem installing fixtures: insert or update on table "preference_questions" violates foreign key constraint "preference_questi_preference_questi_64f61c66_fk_prefer" DETAIL: Key (preference_question_category_id)=(2) is not present in table "preference_question_category"
Иногда он выдает ForeignKeyViolation в зависимости от вышеуказанного случая.
Оказалось, что проблема была в том, что на фикстурах были идентификаторы, эти идентификаторы нельзя было удалить, потому что между объектами были связи. В этом случае есть два варианта, которые я нашел:
- Используйте естественные ключи, как объясняется в этом посте , это заставит вас создать новые методы для естественных ключей и сделать дамп вашей БД .
- Создайте объекты вручную в setUpTestData (трудоемко, но не вызовет проблем)
В зависимости от вашего случая может быть интереснее использовать тот или иной вариант. Тем не менее, первый вариант, вероятно, лучший.