Die meisten Entwickler, die Funktionen zur edx-Plattform hinzugefügt haben, sind damit vertraut ModuleStoreTestCase. Wenn Ihre Tests irgendetwas im Zusammenhang mit Kursunterlageninhalten ausführen (selbst wenn nur ein leerer Kurs erstellt wird), stellt das Erben von dieser Klasse sicher, dass die Daten zwischen den einzelnen Tests ordnungsgemäß bereinigt werden. Dies ist äußerst wertvoll, kann aber in vielen Situationen auch verschwenderisch sein. Während des Hackathons der letzten Woche habe ich erstellt eine schnellere Alternative namens SharedModuleStoreTestCase.
Im Gegensatz zu ModuleStoreTestCase, SharedModuleStoreTestCase tut nur ModuleStore Aufräumen bei TearDownClass() eben. Es soll in Situationen eingesetzt werden, in denen ein oder eine kleine Handvoll Kurse im Voraus initialisiert und dann schreibgeschützt für viele Tests freigegeben werden können. Dieses Nutzungsmuster findet sich häufig in LMS-Tests, die oft einfach denselben Kurs immer wieder neu erstellen erstellen() Methoden.
Auswirkungen auf die Leistung
Um eine Vorstellung von der möglichen Wirkung zu bekommen, habe ich im Rahmen meiner Hackathon-Arbeit einige Testmodule umgestellt. Dies sind nur grobe Zahlen, da sie auf einer relativ geringen Anzahl von Jenkins-Testläufen basieren. Davon abgesehen sind die Ergebnisse vielversprechend:
| Reichen Sie das | # Tests | Vorher | Nach | Delta |
| lms/djangoapps/ccx/tests/test_ccx_modulestore.py | 5 | 38er-Jahre | 4s | -89 % |
| lms/djangoapps/discussion_api/tests/test_api.py | 409 | 2m 45s | 51er-Jahre | -69 % |
| lms/djangoapps/teams/tests/test_views.py | 152 | 1m 17s | 33er-Jahre | -57 % |
Wie konvertieren Sie also Ihre eigenen Tests?
Die Umstellung
Die meisten Klassen, die von erben ModuleStoreTestCase fange mal so an:

Wenn Sie modifizieren selbst.kurs in Ihren individuellen Testfunktionen, dann ist dies perfekt und Sie sollten es weiterhin verwenden ModuleStoreTestCase. Wenn Sie den Kurs jedoch nur einmal einrichten und ihn in Ihren Tests als schreibgeschützt behandeln, können Sie jetzt stattdessen Folgendes tun:

Es ist wichtig, dass die ORM-Vorgänge von Django bestehen bleiben erstellen(). Alle Modelle, die Sie in erstellen setUpClass() muss in Ihrem manuell gelöscht werden TearDownClass() Methode - SharedModuleStoreTestCase wird sie nicht richtig reinigen. Selbst wenn Sie vorsichtig sind, werden Sie wahrscheinlich andere Tests im System auf unvorhersehbare Weise brechen, weil sie schlechte Annahmen über Sequenzen und die erstellten IDs treffen, wenn sie ihre Daten einrichten. Das Debuggen kann sehr mühsam sein.
Wenn wir auf Django 1.8 aktualisieren, können Sie verwenden setUpTestData() zur sicheren Initialisierung von Django-Modellen auf Klassenebene mit automatischer Bereinigung. Bitte warten Sie auf dieses Upgrade und platzieren Sie Modellmanipulationen erstellen() vorerst, auch wenn es etwas langsamer ist.
Welche Tests sollte ich konvertieren?
Der einfachste Ort, um nach Testoptimierungszielen zu suchen, ist die Jenkins-Test-Build-Bericht. Klicken Sie auf „Dauer“, um nach dieser Spalte zu sortieren.

Wir wollen in erster Linie auf teure Tests abzielen, die entweder komplexe Kursdaten erstellen (zB CCX) oder einfache Kursdaten haben, aber viele, viele Tests (zB Diskussionen). Das Erstellen selbst des einfachsten Kurses dauert ungefähr 250-300 ms, was sich wirklich summiert, wenn Tools wie verwendet werden ddt die die Anzahl der Tests in einer Klasse effektiv vervielfachen.
Insgesamt zum Mitnehmen
Der Datenbankzugriff ist ein kostspieliger Teil der Ausführung von Tests, und die ModuleStore ist ein Paradebeispiel dafür. Ich hoffe, dass SharedModuleStoreTestCase kann ein nützliches Werkzeug sein, um die Testausführungszeiten zu verkürzen. Aber darüber hinaus hoffe ich, dass wir durch das Verständnis, warum es funktioniert, im Allgemeinen schnellere Testsuiten entwickeln können.
Dave Ormsbee ist leitender Architekt bei edX. Dieser Beitrag wurde ursprünglich in seinem Blog veröffentlicht, Sumpfschloss.
![]()