Die Ausführung meiner Django-Komponententests dauert lange, daher suche ich nach Möglichkeiten, dies zu beschleunigen. Ich denke darüber nach, eine SSD zu installieren , aber ich weiß, dass dies auch Nachteile hat. Natürlich gibt es Dinge, die ich mit meinem Code tun könnte, aber ich suche nach einer strukturellen Lösung. Selbst das Ausführen eines einzelnen Tests ist langsam, da die Datenbank jedes Mal neu erstellt / nach Süden migriert werden muss. Also hier ist meine Idee ...
Da ich weiß, dass die Testdatenbank immer recht klein sein wird, warum kann ich das System nicht einfach so konfigurieren, dass immer die gesamte Testdatenbank im RAM bleibt? Berühren Sie niemals die Festplatte. Wie konfiguriere ich das in Django? Ich würde es vorziehen, MySQL weiter zu verwenden, da ich dies in der Produktion verwende, aber wenn SQLite 3 oder etwas anderes dies einfach macht, würde ich diesen Weg gehen.
Hat SQLite oder MySQL die Option, vollständig im Speicher ausgeführt zu werden? Es sollte möglich sein, eine RAM-Disk zu konfigurieren und dann die Testdatenbank so zu konfigurieren, dass ihre Daten dort gespeichert werden. Ich bin mir jedoch nicht sicher, wie ich Django / MySQL anweisen soll, ein anderes Datenverzeichnis für eine bestimmte Datenbank zu verwenden, zumal diese immer wieder gelöscht wird und jeden Lauf neu erstellt. (Ich bin auf einem Mac FWIW.)
quelle
"test" in sys.argv
; es kann ausgelöst werden, wenn Sie es nicht möchten, zmanage.py collectstatic -i test
.sys.argv[1] == "test"
ist eine genauere Bedingung, die dieses Problem nicht haben sollte.Normalerweise erstelle ich eine separate Einstellungsdatei für Tests und verwende sie im Testbefehl, z
Es hat zwei Vorteile:
Sie müssen nicht nach
test
einem solchen Zauberwort in sys.argv suchen, estest_settings.py
kann einfach seinOder Sie können es weiter an Ihre Bedürfnisse anpassen und die Testeinstellungen sauber von den Produktionseinstellungen trennen.
Ein weiterer Vorteil ist, dass Sie Tests mit der Produktionsdatenbank-Engine anstelle von sqlite3 ausführen können, um subtile Fehler zu vermeiden
und vor dem Festschreiben von Code einmal ausführen
Nur um sicherzugehen, dass alle Tests wirklich bestanden werden.
quelle
MySQL unterstützt eine Speicher-Engine namens "MEMORY", die Sie in Ihrer Datenbank config (
settings.py
) als solche konfigurieren können :Beachten Sie, dass die MEMORY-Speicher-Engine keine Blob- / Textspalten unterstützt. Wenn Sie
django.db.models.TextField
diese verwenden, funktioniert dies für Sie nicht.quelle
Ich kann Ihre Hauptfrage nicht beantworten, aber Sie können einige Dinge tun, um die Dinge zu beschleunigen.
Stellen Sie zunächst sicher, dass Ihre MySQL-Datenbank für die Verwendung von InnoDB eingerichtet ist. Dann kann es Transaktionen verwenden, um den Status der Datenbank vor jedem Test zurückzusetzen, was meiner Erfahrung nach zu einer massiven Beschleunigung geführt hat. Sie können einen Datenbank-Init-Befehl in Ihrer settings.py übergeben (Django 1.2-Syntax):
Zweitens müssen Sie die Südmigrationen nicht jedes Mal ausführen.
SOUTH_TESTS_MIGRATE = False
Wenn Sie in Ihrer settings.py festlegen, wird die Datenbank mit einer einfachen Synchronisierung erstellt, die viel schneller ist als das Durchlaufen aller historischen Migrationen.quelle
369 tests in 498.704s
auf369 tests in 41.334s
. Das ist mehr als 10 mal schneller!--keep
die Datenbank jedoch beibehalten, ohne dass bei jedem Testlauf Ihr vollständiger Satz von Migrationen erneut angewendet werden muss. Neue Migrationen werden weiterhin ausgeführt. Wenn Sie häufig zwischen Zweigen wechseln, kann es leicht zu einem inkonsistenten Zustand kommen (Sie können neue Migrationen zurücksetzen, bevor Sie wechseln, indem Sie die Datenbank in die Testdatenbank ändern und ausführenmigrate
, dies ist jedoch etwas mühsam).Sie können doppelte Anpassungen vornehmen:
Ich benutze beide Tricks und bin ziemlich glücklich.
So richten Sie es für MySQL unter Ubuntu ein:
Achtung, es dient nur zum Testen, nach dem Neustart geht Ihre Datenbank aus dem Speicher verloren!
quelle
Ein anderer Ansatz: Lassen Sie eine andere Instanz von MySQL in einem tempfs laufen, das eine RAM-Disk verwendet. Anweisungen in diesem Blog-Beitrag: Beschleunigen von MySQL zum Testen in Django .
Vorteile:
quelle
Als Erweiterung der Antwort von Anurag habe ich den Prozess vereinfacht, indem ich dieselben test_settings erstellt und der Datei manage.py Folgendes hinzugefügt habe
scheint sauberer zu sein, da sys bereits importiert ist und manage.py nur über die Befehlszeile verwendet wird, sodass die Einstellungen nicht überladen werden müssen
quelle
"test" in sys.argv
; es kann ausgelöst werden, wenn Sie es nicht möchten, zmanage.py collectstatic -i test
.sys.argv[1] == "test"
ist eine genauere Bedingung, die dieses Problem nicht haben sollte../manage.py
ohne Argumente ausgeführt wird (z. B. um zu sehen, welche Plugins verfügbar sind, wie--help
)len(sys.argv) > 1 and sys.argv[1] == "test"
Verwenden Sie unten in Ihrem
setting.py
quelle