2017-09-04 7 views
2

J'utilise la base de données postgres pré-créée pour mes tests. Voici la configuration pytest:
pytest.ini:Comment puis-je empêcher pytest de supprimer les enregistrements de base de données entre les cas de test?

[pytest] 
norecursedirs = frontend static .svn _build tmp*  
DJANGO_SETTINGS_MODULE = src.settings.testing 
addopts = --reuse-db 

testing.py:

from .base import * 

DEBUG = True 

DATABASES = { 
    'default': { 
     'ENGINE': 'django.contrib.gis.db.backends.postgis', 
     'NAME': 'db', 
     'USER': 'root', 
     'PASSWORD': 'pass', 
     'HOST': 'localhost', 
     'PORT': '5432', 
    } 
} 

appareils de test:

@pytest.fixture(scope='session') 
def user(): 
    return User.objects.create(name='Test',) 

cas de test:

import pytest 

pytestmark = pytest.mark.django_db 


def test_user(user): 
    print(user.pk) # returns pk of newly created user 
    print(User.objects.all()) # returns queryset with one user 


def test_user2(user): 
    print(user.pk) # returns the same value as in the previous test 
    print(User.objects.all()) # returns empty queryset 

Je ne peux pas comprendre le comportement des fixtures pyest. L'instance de modèle est créée une fois par session et elle est la même dans plusieurs cas de test. Mais la valeur réelle de db est différente. Pytest supprime la valeur utilisateur après le premier test.
Comment puis-je empêcher ce comportement et conserver mes enregistrements db enregistrés pour toutes les sessions de test?

+0

Avez-vous essayé de décorer les tests individuellement avec '@ pytest.mark.django_db'? –

+0

@YerayDiazDiaz oui cela fonctionne de la même manière –

Répondre

1

Ce n'est pas un problème de --reuse-db puisque l'utilisateur est retiré d'un test à l'autre dans le même test. Le problème est que vous configurez le projecteur pour avoir une portée session, ce qui signifie que le projecteur sera exécuté une fois par test, et puisque Django videra la base de données entre les tests, votre instance utilisateur n'est plus disponible le deuxième test. Il suffit de retirer la portée du décorateur de fixation:

@pytest.fixture() 
def user(): 
    return User.objects.create(username='Test') 

Edit:. De la pytest-django docs « Une fois que la configuration de la base de données est mise en mémoire cache pour utilisé pour tous les tests ultérieurs et rouleaux arrière opérations pour isoler les tests les uns des autres Cette est le même que le standard Django TestCase utilise la base de données. " Je ne vois pas pourquoi vous voudriez utiliser exactement la même instance User entre les tests, même si vous deviez muter cette instance particulière cela signifierait que les tests dépendraient les uns des autres. Afin d'être en mesure d'isoler les tests, vous devriez être en mesure de fournir l'utilisateur selon les attentes des tests.

+0

mais si je fais cela, alors chaque test recevra un modèle d'utilisateur différent. 'scope = session' fonctionne bien, il maintient l'utilisateur identique entre les cas de test. Mais l'utilisateur est mis en cache quelque part et les enregistrements db réels aka 'User.objects.all()' est vide après le premier test –

+0

S'il vous plaît voir la réponse éditée –

+0

merci pour votre point. Je pense que j'ai mal compris les concepts de base des tests unitaires :) –