wake-up-neo.com

Erkennen Sie den Django-Testmodus

Ich schreibe eine wiederverwendbare Django-App und muss sicherstellen, dass ihre Modelle nur synchronisiert werden, wenn sich die App im Testmodus befindet. Ich habe versucht, einen benutzerdefinierten DjangoTestRunner zu verwenden, fand jedoch keine Beispiele dafür (die Dokumentation zeigt nur, wie ein benutzerdefinierter Testläufer definiert wird).

Hat jemand eine Idee, wie es geht?

EDIT

So mache ich es:

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

Ich hoffe es hilft.

39
Herberth Amaral

Ich denke, die hier gegebene Antwort https://stackoverflow.com/a/7651002/465673 ist viel sauberer:

Fügen Sie dies in Ihre Einstellungen ein.py:

import sys

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

Die ausgewählte Antwort ist ein massiver Hack. :)

Ein weniger massiver Hack besteht darin, eine eigene TestSuiteRunner-Unterklasse zu erstellen und eine Einstellung zu ändern oder das zu tun, was Sie für den Rest Ihrer Anwendung tun müssen. Sie geben den Testläufer in Ihren Einstellungen an:

TEST_RUNNER = 'your.project.MyTestSuiteRunner'

Im Allgemeinen möchten Sie dies nicht tun, aber es funktioniert, wenn Sie es unbedingt benötigen.

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)

HINWEIS: Ab Django 1.8 wurde DjangoTestSuiteRunner nicht mehr unterstützt. Sie sollten stattdessen DiscoverRunner verwenden:

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

Nicht ganz sicher über Ihren Anwendungsfall, aber eine Möglichkeit, die ich bei laufender Testsuite erkannt habe, ist zu prüfen, ob Django.core.mail ein outbox-Attribut hat, wie beispielsweise:

from Django.core import mail

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

Dieses Attribut wird vom Django-Testläufer in setup_test_environment hinzugefügt und in teardown_test_environment entfernt. Sie können die Quelle hier überprüfen: https://code.djangoproject.com/browser/Django/trunk/Django/test/utils.py

Bearbeiten: Wenn Sie möchten, dass Modelle nur zum Testen definiert werden, sollten Sie das Django-Ticket # 7835 insbesondere Kommentar # 24 einen Teil davon auschecken:

Anscheinend können Sie Modelle direkt in tests.py definieren. Syncdb importiert niemals tests.py, sodass diese Modelle nicht mit der normalen Datenbank synchronisiert werden. Sie werden jedoch mit der Testdatenbank synchronisiert und können in Tests verwendet werden.

18
Mark Lavin

Ich verwende die Einstellungen von settings.py. Ich habe ein globales settings.py, das die meisten Sachen enthält, und dann habe ich Überschreibungen dafür. Jede Einstellungsdatei beginnt mit:

from myproject.settings import settings

und überschreibt dann einige Einstellungen.

  • prod_settings.py - Produktionseinstellungen (z. B. überschreibt DEBUG = False)
  • dev_settings.py - Entwicklungseinstellungen (z. B. mehr Protokollierung)
  • test_settings.py

Und dann kann ich UNIT_TESTS = False in der Basiseinstellungen.py definieren und es in test_settings.py auf UNIT_TESTS = True setzen.

Wenn ich dann einen Befehl ausführe, muss ich entscheiden, welche Einstellungen ausgeführt werden sollen (z. B. Django_SETTINGS_MODULE=myproject.test_settings ./manage.py test). Ich mag diese Klarheit.

7

Nun, Sie können Umgebungsvariablen einfach auf diese Weise verwenden:

export MYAPP_TEST=1 && python manage.py test

dann in deiner settings.py-Datei:

import os

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

if TEST:
    # Do something
0
turkus