2013-08-22 18 views
6

Ho scritto test di Django usando django.test.TestCase e mi piacerebbe utilizzare un dispositivo con tutti i dati del mio database corrente per eseguire i test. Tuttavia, se creo l'apparecchio come segue:Django manage.py test non può caricare correttamente il dispositivo

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

quando ho quindi eseguire il test utilizzando python manage.py test myapp, ottengo il seguente errore:

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. 

Ho letto da qualche parte, in modo che questo potrebbe essere causato da un conflitto pk così ho poi provato a ricreare l'apparecchio con:

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

Ma ora l'esecuzione del test mi dà:

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

Ho anche provato in vari modi ad esclusione (utilizzando l'opzione --exclude) auth.permission e contenttypes (o entrambi contemporaneamente), ma poi ho ottenere lamentele sulle autorizzazioni mancanti (Key (permission_id)=(44) is not present in table "auth_permission".) o tipi di contenuto mancanti (DeserializationError: ContentType matching query does not exist.)

Il La cosa è che ho bisogno di permessi comunque perché i miei test sono in parte per verificare che solo gli utenti con permessi specifici possano accedere ad alcune visualizzazioni.

Non capisco perché questo sta accadendo, ad essere onesti - la mia impressione è che il test runner inizia con un database completamente pulito e carica TUTTO il mio apparecchio, ma leggere post come questo: Django unit-testing with loading fixtures for several dependent applications problems fa sembrare come forse non è il caso.

Come posso aggirare questo? Preferirei mille volte non c'è bisogno di scrivere cose come User.objects.create_user(.. tonnellate di volte sotto def setUp(self): nel mio test solo per avere abbastanza oggetti per loro di correre correttamente ...

risposta

3

Quando si esegue un test del initial_data fixtures will be loaded (by syncdb).

Per me dumpdata opere con l'argomento --natural, ad esclusione del contenttypes e quindi l'eliminazione di alcune voci auth.permission manualmente che solo questi rimangono:

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

Non capisco esattamente centrale perché, ma funziona. Proverei a confrontare il mio dispositivo con una copia di un nuovo database direttamente dopo lo syncdb e decidere quindi cosa eliminare o modificare nel mio dispositivo. Spero che questo aiuti nel tuo caso.

1

Il problema sembra essere stato presente, anche con - naturale. Tuttavia, sembra essere risolto in django1.9 con nuove bandiere: dumpdata --natural-foreign --natural-primary

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

+1

Per chiunque trovare questo con un problema simile, ecco un'intuizione fondamentale: se voi modelli contengono una relazione M2M, NON scaricare la tabella M2M nell'attrezzatura di prova! In caso contrario, il M2M verrà popolato per la prima volta quando vengono creati gli oggetti correlati e quindi AGAIN quando i dati M2M vengono caricati dal dispositivo, causando quindi un errore di integrità. – powderflask

Problemi correlati