Startseite / Artikel / Kürzung von Jest-Ausführungen lokal und in CI: Workers, Caching und Scope

Kürzung von Jest-Ausführungen lokal und in CI: Workers, Caching und Scope

Eine praktische Checkliste für schnellere Jest-Suiten: Zuerst messen, Worker anpassen, globale Einrichtungen reduzieren, den Cache wiederverwenden, isolatedModules nutzen und nur die betroffenen Tests ausführen.

956 Wörter

Eine langsame Testsuite verändert leise, wie ein Team arbeitet: Die Mitarbeiter führen Tests seltener durch, übertragen Code in das CI-System, um Ergebnisse zu erhalten, und warten am längsten genau dann, wenn sie es sich am wenigsten leisten können – während eines Hotfixes in der Produktion. Dieser Aufwand steigt, wenn KI-basierte Programmierassistenten Änderungen schnell erstellen und die Testsuite als Hauptsicherheitsnetz dient. Jest bietet viele Konfigurationsmöglichkeiten sowie sinnvolle Standardwerte, sodass die Ausgangslage in der Regel bereits gut ist. Dennoch können einige Anpassungen die Laufzeiten sowohl auf einem Laptop als auch im CI-System deutlich verkürzen. Keine dieser Anpassungen ist besonders ausgefallen; zusammen bilden sie eine nützliche Checkliste.

Messen, bevor man optimiert

Jede der folgenden Änderungen hat einen Aufwand oder ein Kompromiss, daher sollte man mit Zahlen beginnen. Messen Sie die Gesamtlaufzeit mit deaktiviertem Cache (jest --no-cache), um eine Ausgangswertbasis zu erhalten, und wenden Sie anschließend nacheinander Änderungen an und messen erneut.

Parallelisierung an die Maschine anpassen

Jest führt Testdateien standardmäßig in parallelen Worker-Prozessen aus, was in der Regel gut ist, aber nicht immer optimal. Zwei Flags steuern dies:

  • --runInBand führt alle Tests seriell im aktuellen Prozess ohne Worker aus. Dies kann bei serverseitigen Projekten, deren Tests eine teure Ressource gemeinsam nutzen, oder auf CI-Systemen mit sehr wenigen Kernen schneller sein, da das Erstellen von Worker-Prozessen mehr Kosten verursacht, als es einspart.
  • --maxWorkers legt fest, wie viele Worker Jest erstellt. Es kann eine Zahl oder ein Prozentsatz der verfügbaren Kerne angegeben werden; 50% ist ein vernünftiger Ausgangspunkt, der Platz für den Rest des Systems lässt.

Der richtige Wert hängt von der Hardware ab, daher sollten Sie ihn lokal sowie auf Ihren CI-Systemen getrennt messen. CI-Maschinen geben oft mehr Kerne an, als sie unter Last tatsächlich nutzen können, und eine Überbelegung verlangsamt die Tests statt sie zu beschleunigen.

Halten Sie die globale Konfiguration übersichtlich

Eine globale Konfigurationsdatei ist in einer großen Codebasis praktisch: Mocks, Polyfills und Test-Tools werden einmal registriert, und jeder Test erhält sie. Das Problem ist, dass jede Testdatei den gesamten Aufwand tragen muss – auch Dateien, die davon nichts benötigen. Schwere Importe, Datenbank-Fixtures oder große Mock-Register in setupFilesAfterEnv können sonst millisekundenschnelle Unit-Tests in langsame verwandeln.

Bewegen Sie aufwändige Konfigurationen näher zu den Tests, die sie benötigen: einen explizit importierten Helper, ein beforeAll in der entsprechenden Datei oder ein separates Jest-Projekt mit eigener Konfiguration für Integrationstests.

Wiederverwenden Sie den Cache

Zweite Ausführungen sind in der Regel schneller als die ersten, weil Jest umgewandelte Dateien sowie andere Metadaten cachet. Das merkt man am deutlichsten im Watch-Modus, doch auch CI-Vorgänge profitieren, wenn der Cache zwischen den Jobs erhalten bleibt. Weisen Sie cacheDirectory auf einen stabilen Pfad hin und sichern Sie ihn mit der Caching-Funktion Ihres CI-Systems – unter Verwendung des Lockfiles und der Jest-Konfiguration – damit jede Pipeline nicht von vorne beginnen muss.

Watch-Modus lokal verwenden

Für lokale Arbeit bietet jest --watch den besten Feedback-Zyklus, den Jest bereitstellt. Er führt nur die Tests aus, die mit geänderten Dateien zusammenhängen, und seine interaktive Eingabe ermöglicht es Ihnen, nach Dateinamen oder Testnammemustern zu filtern. Er ist nicht für CI vorgesehen: Eine Pipeline benötigt eine einzige Ausführung, die mit einem Statuscode endet – daher sollten Sie den Watch-Modus auf Entwicklerrechnern nutzen.

IsolatedModules für TypeScript aktivieren

Wenn TypeScript-Tests mit ts-jest ausgeführt werden, verursacht die vollständige Typüberprüfung jedes Files erhebliche Zusatzbelastung. Durch Aktivierung von isolatedModules kompiliert der Transformer jedes File eigenständig, ohne Typinformationen aus dem Rest des Programms. Teams berichten in Angular-Projekten von deutlichen Geschwindigkeitssteigerungen, und man gibt nur sehr wenig an Sicherheit auf, solange tsc --noEmit oder der Editor weiterhin die Codebasis typüberprüft. Wo genau sich diese Option befindet, hängt von der Version von ts-jest ab – prüfen Sie daher die aktuelle Dokumentation.

Testen Sie nur das, was durch eine Änderung beeinflusst wird

Es gibt keinen Grund, das gesamte Suite auszuführen, nur weil sich ein einzelnes Paket geändert hat. Jest selbst kann die Ausführung mit --onlyChanged oder --changedSince=<branch> einschränken, wobei dabei Versionskontrollsysteme genutzt werden, um verwandte Tests zu finden. In einem Monorepo geht ein Build-System wie Nx noch einen Schritt weiter, indem es den Projektgraphen versteht und nur die Tests für die von der aktuellen Änderung betroffenen Projekte ausführt.

Bewahren Sie zumindest eine vollständige Ausführung irgendwo auf, beispielsweise auf der Hauptbranche oder täglich nachts, um alles zu erkennen, was die Abhängigkeitsanalyse übersehen könnte.

Betrachten Sie Vitest

Vitest ist weitgehend mit der Jest-API kompatibel, wird aktiv gepflegt und funktioniert mit den gängigen JavaScript-Frameworks, einschließlich Nuxt. Für Projekte, die bereits auf Vite basieren, ist es oft die natürlichere Wahl, und viele Teams greifen bei neuen Projekten zunächst darauf zurück. Der größte Teil der oben genannten Ratschläge – wie das Messen von Leistung, Begrenzung der Worker-Zahl, eine schlanke Einrichtung sowie das Ausführen nur der betroffenen Tests – gilt genauso für Vitest. Wenn Sie in Erwägung ziehen, einen Drittanbieter-Testlaufmechanismus vollständig zu ersetzen, lesen Sie „Jest durch Node’s nativen Testlaufmechanismus ersetzen“.

Wenn das Optimieren des Software-Systems nicht mehr hilft

Irgendwann übertrifft keine Konfigurationsänderung schnelleres Hardware. Ein neuer Laptop oder ein größeres, selbst gehostetes CI-System kann die günstigste weitere Verbesserung sein, sobald das Testframework selbst in gutem Zustand ist.

Haupterkenntnisse

  • Erstellen Sie eine kalte, nicht gekachelte Baseline und ändern Sie jeweils nur ein Element.
  • Passen Sie --maxWorkers oder --runInBand an die tatsächliche Kapazität jeder Umgebung an.
  • Verlagern Sie aufwändige Einrichtungen aus den globalen Hooks in die Tests, die sie benötigen.
  • Speichern Sie den Jest-Cache über mehrere CI-Ausführungen hinweg; verwenden Sie den Überwachungsmodus nur lokal.
  • Lassen Sie isolatedModules die typische Überprüfung pro Datei aus, während ein separater tsc-Schritt die Typen korrekt prüft.
  • Führen Sie auf Feature-Branches nur die betroffenen Tests aus und auf main den vollständigen Testumfang.