2013-08-22 8 views
6

Ich habe Django-Tests mit django.test.TestCase geschrieben, und ich würde gerne ein Fixture mit all meinen aktuellen Datenbankdaten verwenden, um die Tests durchzuführen. wenn ich das Gerät jedoch wie folgt erstellen:Django manage.py test kann Fixture nicht richtig laden

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

wenn ich dann die Tests ausführen python manage.py test myapp verwenden, erhalte ich folgende Fehlermeldung:

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. 

ich irgendwo auf SO lesen, dass dies verursacht wird durch ein Stück Konflikt so habe ich versucht, das Gerät mit dann neu zu erstellen:

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

Aber jetzt die Durchführung des Tests gibt mir:

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

ich auch verschiedentlich ohne ausprobiert habe (mit der Option --exclude) auth.permission und contenttypes (oder beides gleichzeitig), aber dann habe ich Beschwerden bekommen über fehlende Berechtigungen (Key (permission_id)=(44) is not present in table "auth_permission".) oder fehlende Inhaltstypen (DeserializationError: ContentType matching query does not exist.)

Die Das Problem ist, dass ich trotzdem Berechtigungen benötige, da meine Tests teilweise sicherstellen, dass nur Benutzer mit bestimmten Berechtigungen auf bestimmte Ansichten zugreifen können.

Ich verstehe nicht, warum das passiert, um ehrlich zu sein - mein Eindruck war, dass der Testläufer mit einer völlig sauberen Datenbank beginnt und alles von meinem Gerät lädt, aber lesen Beiträge wie dieses: Django unit-testing with loading fixtures for several dependent applications problems macht es scheint vielleicht ist das nicht der Fall.

Wie kann ich das umgehen? Ich würde viel lieber nicht Sachen schreiben wie User.objects.create_user(.. Tonnen mal unter def setUp(self): in meinen Tests gerade genug, um Objekte zu haben, um sie richtig zu laufen ...

Antwort

3

Wenn Sie einen Test der initial_data fixtures will be loaded (by syncdb) laufen.

Für mich dumpdata Arbeiten mit dem --natural Argument, das contenttypes ohne und dann das Löschen einige auth.permission Einträge manuell, dass nur diese bleiben:

{ 
    "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" 
     ] 
    } 
}, 

Ich verstehe nicht, warum excactly, aber es funktioniert. Ich würde versuchen, mein Gerät mit einem Dump einer frischen Datenbank direkt nach syncdb zu vergleichen und dann zu entscheiden, was ich in meinem Fixture löschen oder bearbeiten möchte. Hoffe das hilft in deinem Fall.

1

Das Problem scheint immer noch vorhanden zu sein, sogar mit --natürlich. es jedoch in django1.9 mit neuen Fahnen scheint aufgelöst zu werden: dumpdata --natural-foreign --natural-primary

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

+1

Für alle diese mit einem ähnlichen Problem zu finden, hier ist eine wichtige Erkenntnis: wenn Sie Modelle eine M2M-Beziehung enthalten, Werfen Sie den M2M-Tisch NICHT in Ihre Testhalterung! Andernfalls wird der M2M zuerst gefüllt, wenn die zugehörigen Objekte erstellt werden, und dann erneut, wenn die M2M-Daten von der Vorrichtung geladen werden, wodurch ein Integritätsfehler verursacht wird. – powderflask