Тест Django manage.py не может правильно загрузить прибор

Я написал тесты Django с помощью django.test.TestCase, и я хотел бы использовать прибор со всеми моими текущими данными базы данных для запуска тестов. Однако, если я создаю прибор следующим образом:

python manage.py dumpdata --indent=3 > myapp/fixtures/test_data.json

когда я запускаю тесты с помощью python manage.py test myapp, я получаю следующую ошибку:

Problem installing fixture...(traceback)
IntegrityError: Could not load auth.Permission(pk=42): duplicate key value violates unique constraint "auth_permission_content_type_id_codename_key"
DETAIL: Key (content_type_id, codename)=(14, add_record) already exists.

Я где-то читал SO, что это может быть вызвано конфликтом pk, поэтому я попытался повторно создать прибор с помощью:

python manage.py dumpdata --natural --indent=3 > myapp/fixtures/test_data.json

Но теперь запуск теста дает мне:

Problem installing fixture...(traceback)
DeserializationError: 'NoneType' object has no attribute '_meta'

Я также пробовал по-разному исключать (используя параметр --exclude) auth.permission и contenttypes (или оба одновременно), но затем я получаю жалобы о недостающих разрешениях (Key (permission_id)=(44) is not present in table "auth_permission".) или отсутствующих типах контента (DeserializationError: ContentType matching query does not exist.)

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

Я не понимаю, почему это происходит, если честно, мое впечатление было то, что тестовый бегун начинается с полностью чистой базы данных и загружает ВСЕ из моего прибора, но чтение сообщений вроде этого: Единичное тестирование Django с загрузкой для нескольких зависимых задач приложений, похоже, что это не так.

Как я могу обойти это? Я бы предпочел не писать такие вещи, как User.objects.create_user(.. тонны раз под def setUp(self): в моих тестах, чтобы иметь достаточно объектов, чтобы они могли нормально работать...

2 ответа

Когда вы запустите тест, будут загружены initial_data светильники (через syncdb).

Для меня dumpdata работает с аргументом --natural, за исключением contenttypes, а затем удаляется несколько записей auth.permission, которые только остаются:

{
 "pk": 1, 
 "model": "auth.permission", 
 "fields": {
 "codename": "add_permission", 
 "name": "Can add permission", 
 "content_type": [
 "auth", 
 "permission"
 ]
 }
},
{
 "pk": 2, 
 "model": "auth.permission", 
 "fields": {
 "codename": "change_permission", 
 "name": "Can change permission", 
 "content_type": [
 "auth", 
 "permission"
 ]
 }
},
{
 "pk": 3, 
 "model": "auth.permission", 
 "fields": {
 "codename": "delete_permission", 
 "name": "Can delete permission", 
 "content_type": [
 "auth", 
 "permission"
 ]
 }
},
{
 "pk": 4, 
 "model": "auth.permission", 
 "fields": {
 "codename": "add_group", 
 "name": "Can add group", 
 "content_type": [
 "auth", 
 "group"
 ]
 }
},
{
 "pk": 5, 
 "model": "auth.permission", 
 "fields": {
 "codename": "change_group", 
 "name": "Can change group", 
 "content_type": [
 "auth", 
 "group"
 ]
 }
},
{
 "pk": 6, 
 "model": "auth.permission", 
 "fields": {
 "codename": "delete_group", 
 "name": "Can delete group", 
 "content_type": [
 "auth", 
 "group"
 ]
 }
},
{
 "pk": 7, 
 "model": "auth.permission", 
 "fields": {
 "codename": "add_user", 
 "name": "Can add user", 
 "content_type": [
 "auth", 
 "user"
 ]
 }
},
{
 "pk": 8, 
 "model": "auth.permission", 
 "fields": {
 "codename": "change_user", 
 "name": "Can change user", 
 "content_type": [
 "auth", 
 "user"
 ]
 }
},
{
 "pk": 9, 
 "model": "auth.permission", 
 "fields": {
 "codename": "delete_user", 
 "name": "Can delete user", 
 "content_type": [
 "auth", 
 "user"
 ]
 }
},
{
 "pk": 10, 
 "model": "auth.permission", 
 "fields": {
 "codename": "add_contenttype", 
 "name": "Can add content type", 
 "content_type": [
 "contenttypes", 
 "contenttype"
 ]
 }
},
{
 "pk": 11, 
 "model": "auth.permission", 
 "fields": {
 "codename": "change_contenttype", 
 "name": "Can change content type", 
 "content_type": [
 "contenttypes", 
 "contenttype"
 ]
 }
},
{
 "pk": 12, 
 "model": "auth.permission", 
 "fields": {
 "codename": "delete_contenttype", 
 "name": "Can delete content type", 
 "content_type": [
 "contenttypes", 
 "contenttype"
 ]
 }
},
{
 "pk": 13, 
 "model": "auth.permission", 
 "fields": {
 "codename": "add_session", 
 "name": "Can add session", 
 "content_type": [
 "sessions", 
 "session"
 ]
 }
},
{
 "pk": 14, 
 "model": "auth.permission", 
 "fields": {
 "codename": "change_session", 
 "name": "Can change session", 
 "content_type": [
 "sessions", 
 "session"
 ]
 }
},
{
 "pk": 15, 
 "model": "auth.permission", 
 "fields": {
 "codename": "delete_session", 
 "name": "Can delete session", 
 "content_type": [
 "sessions", 
 "session"
 ]
 }
},
{
 "pk": 16, 
 "model": "auth.permission", 
 "fields": {
 "codename": "add_site", 
 "name": "Can add site", 
 "content_type": [
 "sites", 
 "site"
 ]
 }
},
{
 "pk": 17, 
 "model": "auth.permission", 
 "fields": {
 "codename": "change_site", 
 "name": "Can change site", 
 "content_type": [
 "sites", 
 "site"
 ]
 }
},
{
 "pk": 18, 
 "model": "auth.permission", 
 "fields": {
 "codename": "delete_site", 
 "name": "Can delete site", 
 "content_type": [
 "sites", 
 "site"
 ]
 }
},

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


Проблема все еще присутствует, даже с --естественным. Однако, похоже, это разрешено в django1.9 с новыми флагами:   dumpdata --natural-foreign --natural-primary

см. https://code.djangoproject.com/ticket/21278#comment:5

licensed under cc by-sa 3.0 with attribution.