Skracanie Jest działa lokalnie i w CI: Workers, Caching oraz Scope
Praktyczna lista kontrolna dla szybszych zestawów Jest: pomiar najpierw, optymalizacja procesorów, redukcja globalnego ustawienia, ponowne wykorzystanie pamięci cache, opcja isolatedModules oraz uruchamianie tylko dotkniętych testów.
Powolny zestaw testów po cichu zmienia sposób pracy zespołu: ludzie rzadziej uruchamiają testy, wysyłają kod do CI, by to sprawdzić, i czekają najdłużej dokładnie wtedy, gdy mogą sobie na to najmniej pozwolić – podczas szybkiego naprawiania błędów w produkcji. Koszt ten rośnie, gdy asystenci do pisania kodu oparte na AI szybko generują zmiany, a zestaw testów stanowi główną sieć bezpieczeństwa. Jest dostarczany z wieloma opcjami konfiguracji oraz rozsądnymi ustawieniami domyślnymi, więc doświadczenie bez dodatkowych zmian jest zazwyczaj w porządku, ale kilka dostosowań może znacząco skrócić czas wykonywania testów zarówno na laptopie, jak i w CI. Żadne z nich nie jest skomplikowane; razem tworzą przydatną listę kontrolną.
Mierz przed dostosowywaniem
Każda z poniższych zmian ma swój koszt lub wymaga kompromisu, więc zacznij od liczb. Zmierz czas pełnego wykonywania testów z wyłączonym cache’em (jest --no-cache), aby uzyskać bazową wartość, a następnie wprowadzaj po jednej zmianie i ponownie mierz.
Dostosuj poziom równoległości do możliwości maszyny
Domyślnie Jest uruchamia pliki testowe równolegle w procesach roboczych, co zazwyczaj jest dobre, ale nie zawsze optymalne. Dwie flagi to kontrolują:
--runInBanduruchamia wszystkie testy sekwencyjnie w bieżącym procesie bez procesów roboczych. Może to być szybsze w projektach serwerowych, których testy korzystają z kosztownego zasobu, lub w narzędziach CI z bardzo małą liczbą rdzeni, gdzie tworzenie procesów roboczych kosztuje więcej, niż oszczędza.--maxWorkersokreśla, ilu procesów roboczych ma uruchomić Jest. Przyjmuje liczbę lub procent dostępnych rdzeni;50%to rozsądny punkt wyjścia, który pozostawia margines dla reszty maszyny.
Odpowiednia wartość zależy od sprzętu, dlatego należy ją zmierzyć lokalnie oraz osobno na narzędziach CI. Maszyny CI często podają większą liczbę rdzeni, niż faktycznie mogą wykorzystać pod obciążeniem, a ich przeciążenie powoduje wolniejsze, a nie szybsze testy.
Zachowaj lżek układ globalny
Plik konfiguracji globalnej jest przydatny w dużych bazach kodu: można raz zarejestrować mocki, polyfilli oraz narzędzia testowe, a każdy test będzie miał do nich dostęp. Problem polega na tym, że każdy plik testowy płaci za to wszystko, włączając te pliki, które tego w ogóle nie potrzebują. Ciężkie importy, dane bazodanowe lub duże rejestracje mocków w setupFilesAfterEnv mogą przekształcić inaczej błyskawicznie szybkie testy jednostkowe w wolne.
Przenieś kosztowną konfigurację bliżej testów, które jej potrzebują: pomocnik importowany wyraźnie, beforeAll w odpowiednim pliku lub oddzielny projekt Jest z własną konfiguracją dla testów integracyjnych.
Wykorzystuj ponownie pamięć cache
Druga eksploatacja jest zazwyczaj szybsza od pierwszej, ponieważ Jest przechowuje w pamięci tymczasowej przetworzone pliki oraz inne metadane. Najbardziej odczuwalne to jest w trybie obserwacji, ale systemy CI również czerpią korzyści, jeśli pamięć tymczasowa pozostaje nienaruszona między zadaniami. Ustaw pole cacheDirectory na stabilną ścieżkę i utrwal je za pomocą funkcji cacheowania w Twoim systemie CI, używając jako klucza pliku lockfile oraz konfiguracji Jest, aby każda pipeline nie musiała rozpoczynać się od nowa.
Używanie trybu obserwacji lokalnie
Dla pracy lokalnej jest --watch to najlepszy mechanizm sprzężenia zwrotnego oferowany przez Jest. Uruchamia on ponownie tylko te testy, które dotyczą zmienionych plików, a interaktywne pole wprowadzania pozwala filtrować według nazwy pliku lub wzoru nazwy testu. Nie jest przeznaczony do systemów CI – pipeline wymagają pojedynczej eksploatacji, która kończy się kodem stanu, dlatego tryb obserwacji należy zachować na maszynach programistów.
Włączenie izolowanych modułów dla TypeScript
Gdy testy w TypeScriptie są przeprowadzane za pomocą ts-jest, pełna weryfikacja typów każdego pliku powoduje znaczną nadmiarową pracę. Włączenie opcji isolatedModules sprawia, że transformator kompiluje każdy plik osobno, bez informacji o typach z reszty programu. Zespoły zgłaszają wyraźne przyspieszenia w projektach Angular dzięki temu rozwiązaniu, a bezpieczeństwo kodu praktycznie nie ulega zmianie, o ile nadal używa się opcji tsc --noEmit lub edytora, który weryfikuje typy w bazie kodu. Miejsce znajdowania tej opcji zależy od wersji ts-jest, dlatego należy sprawdzić aktualną dokumentację.
Testuj tylko to, co jest dotknięte zmianą
Nie ma powodu do uruchamiania całego zestawu testów z powodu zmiany dotyczącej tylko jednego pakietu. Sam Jest pozwala zawęzić zakres testów za pomocą flag --onlyChanged lub --changedSince=<branch>, które wykorzystują system kontroli wersji do znalezienia powiązanych testów. W monorepo systemy budowania takie jak Nx idą o krok dalej, analizując strukturę projektu i uruchamiając testy tylko dla tych projektów, które są dotknięte aktualną zmianą.
Zachowaj przynajmniej jedno pełne uruchomienie testów w jakimś miejscu, na przykład na gałęzi main lub co noc, aby wykryć wszystko, czego nie dostrzeże analiza zależności.
Rozważ Vitest
Vitest jest w dużej mierze kompatybilny z API Jest, jest aktywnie utrzymywany i działa z popularnymi frameworkami JavaScript, w tym Nuxt. Dla projektów już zbudowanych przy użyciu Vite jest często bardziej naturalnym wyborem, a wiele zespołów decyduje się na niego jako pierwszy przy nowych projektach. Większość powyższych zaleceń – mierzenie wydajności, ograniczenia procesów pracujących, prosta konfiguracja oraz uruchamianie tylko testów dotkniętych problemami – odnosi się również do Vitest. Jeśli rozważasz całkowite porzucenie zewnętrznego narzędzia do testowania, zapoznaj się z zastąpieniem Jest narzędziem testowym wbudowanym w Node.
Gdy optymalizacje oprogramowania przestają pomagać
Ostatecznie żadna zmiana konfiguracji nie przebije szybszego sprzętu. Nowszy laptop lub większy, samodzielnie zarządzany runner CI może być najtańszym sposobem na dalsze ulepszenia, gdy sama seria testów jest już dobrze przygotowana.
Główne wnioski
- Ustal bazę startową bez wykorzystania cache’u i zmieniaj jedną rzecz naraz.
- Dostosuj
--maxWorkerslub--runInBanddo rzeczywistej pojemności każdego środowiska. - Przenieś kosztowne procedury konfiguracji z globalnych hooków do testów, które je wymagają.
- Zachowuj cache Jest między kolejnymi uruchomieniami CI; używaj trybu watch tylko lokalnie.
- Pozwól
isolatedModulespomijać sprawdzanie typów na poziomie poszczególnych plików, podczas gdy oddzielny kroktsczapewnia dokładność typów. - Uruchamiaj tylko te testy, które są dotknięte zmianami na gałęziach funkcjonalnych, a pełny zestaw testów na gałęzi main.