web-dev-qa-db-fra.com

Détecter le mode de test Django

J'écris une application Django réutilisable et je dois m'assurer que ses modèles ne sont synchronisés que lorsque l'application est en mode test. J'ai essayé d'utiliser un DjangoTestRunner personnalisé, mais je n'ai trouvé aucun exemple d'utilisation (la documentation n'indique que la définition d'un programme d'exécution de test personnalisé).

Alors, est-ce que quelqu'un a une idée de comment le faire?

MODIFIER

Voici comment je le fais:

#in settings.py
import sys
TEST = 'test' in sys.argv

J'espère que ça aide.

39
Herberth Amaral

Je pense que la réponse fournie ici https://stackoverflow.com/a/7651002/465673 est une façon beaucoup plus simple de le faire:

Mettez ceci dans votre settings.py:

import sys

TESTING = sys.argv[1:2] == ['test']
41
jjmaestro

La réponse choisie est un piratage massif. :)

Un hack moins massif serait de créer votre propre sous-classe TestSuiteRunner et de modifier un paramètre ou de faire tout ce que vous aurez besoin pour le reste de votre application. Vous spécifiez le testeur dans vos paramètres:

TEST_RUNNER = 'your.project.MyTestSuiteRunner'

En général, vous ne voulez pas faire cela, mais cela fonctionne si vous en avez absolument besoin.

from Django.conf import settings
from Django.test.simple import DjangoTestSuiteRunner

class MyTestSuiteRunner(DjangoTestSuiteRunner):
    def __init__(self, *args, **kwargs):
        settings.IM_IN_TEST_MODE = True
        super(MyTestSuiteRunner, self).__init__(*args, **kwargs)

NOTE: Depuis Django 1.8, DjangoTestSuiteRunner est obsolète. Vous devriez utiliser DiscoverRunner à la place:

from Django.conf import settings
from Django.test.runner import DiscoverRunner


class MyTestSuiteRunner(DiscoverRunner):
    def __init__(self, *args, **kwargs):
        settings.IM_IN_TEST_MODE = True
        super(MyTestSuiteRunner, self).__init__(*args, **kwargs)
41
Travis Jensen

Je ne suis pas tout à fait sûr de votre cas d'utilisation, mais l'un des moyens permettant de détecter le déroulement de la suite de tests consiste à vérifier si Django.core.mail possède un attribut outbox tel que:

from Django.core import mail

if hasattr(mail, 'outbox'):
    # We are in test mode!
    pass
else:
    # Not in test mode...
    pass

Cet attribut est ajouté par le lanceur de tests Django dans setup_test_environment et supprimé dans teardown_test_environment. Vous pouvez vérifier la source ici: https://code.djangoproject.com/browser/Django/trunk/Django/test/utils.py

Edit: Si vous voulez que les modèles soient uniquement testés, vous devriez vérifier le billet Django # 7835 en particulier le commentaire # 24 dont une partie est donnée ci-dessous:

Apparemment, vous pouvez simplement définir des modèles directement dans votre tests.py. Syncdb n'important jamais tests.py, ces modèles ne seront donc pas synchronisés avec la base de données normale, mais ils seront synchronisés avec la base de données de test et pourront être utilisés dans des tests.

18
Mark Lavin

J'utilise les paramètres settings.py. J'ai un global settings.py, qui contient la plupart des choses, et puis j'ai des remplacements pour cela. Chaque fichier de paramètres commence par:

from myproject.settings import settings

et continue ensuite pour remplacer certains des paramètres.

  • prod_settings.py - Paramètres de production (par exemple, remplace DEBUG = False)
  • dev_settings.py - Paramètres de développement (par exemple, plus de journalisation)
  • test_settings.py

Et puis je peux définir UNIT_TESTS = False dans le fichier settings.py de base et le remplacer par UNIT_TESTS = True dans test_settings.py.

Ensuite, chaque fois que j'exécute une commande, je dois choisir les paramètres à utiliser (par exemple, Django_SETTINGS_MODULE=myproject.test_settings ./manage.py test). J'aime cette clarté.

7
Amichai Schreiber

Eh bien, vous pouvez simplement utiliser les variables d’environnement de cette façon:

export MYAPP_TEST=1 && python manage.py test

puis dans votre fichier settings.py:

import os

TEST = os.environ.get('MYAPP_TEST')

if TEST:
    # Do something
0
turkus