Accueil / Articles / Raccourcissement des exécutions de Jest en local et dans CI : Workers, mise en cache et portée

Raccourcissement des exécutions de Jest en local et dans CI : Workers, mise en cache et portée

Une liste de contrôle pratique pour accélérer les suites Jest : mesurer d’abord, ajuster les travailleurs, réduire la configuration globale, réutiliser le cache, activer isolatedModules, et ne lancer que les tests concernés.

956 mots

Un ensemble de tests lent modifie silencieusement la façon dont une équipe travaille : les personnes exécutent moins souvent des tests, soumettent leurs modifications au CI pour obtenir des résultats, et attendent le plus longtemps justement quand elles en ont le moins besoin, pendant une correction d’urgence en production. Ce coût augmente lorsque des assistants de codage basés sur l’IA génèrent rapidement des modifications et que cet ensemble de tests constitue le principal filet de sécurité. Jest dispose de nombreuses options de configuration ainsi que de valeurs par défaut judicieuses, ce qui permet généralement d’obtenir de bons résultats dès le départ, mais quelques ajustements peuvent réduire considérablement les temps d’exécution, que ce soit sur un ordinateur portable ou dans le CI. Aucun de ces ajustements n’est particulièrement complexe ; ensemble, ils forment une liste de contrôle utile.

Mesurez avant d’ajuster

Chaque modification comporte un coût ou un compromis, il faut donc commencer par des chiffres. Mesurez le temps d’exécution complet avec le cache désactivé (jest --no-cache) pour obtenir une valeur de référence, puis appliquez une modification à la fois et mesurez à nouveau.

Ajustez le niveau de parallélisme en fonction de la machine

Jest exécute les fichiers de test en parallèle via des processus travailleurs par défaut, ce qui est généralement bon, mais pas toujours optimal. Deux paramètres le contrôlent :

  • --runInBand exécute tous les tests en série dans le processus actuel sans travailleurs. Cela peut être plus rapide pour les projets côté serveur dont les tests partagent une ressource coûteuse, ou sur des outils CI disposant de très peu de cœurs, où la création de travailleurs coûte plus que ce qu’ils permettent d’économiser.
  • --maxWorkers définit le nombre de travailleurs que Jest crée. Il accepte un nombre ou un pourcentage des cœurs disponibles ; 50% constitue un point de départ raisonnable qui laisse de la marge pour le reste du système.

La valeur idéale dépend du matériel, il faut donc mesurer localement ainsi que sur les outils CI séparément. Les machines CI indiquent souvent plus de cœurs qu’elles ne peuvent réellement utiliser sous charge, et en attribuer trop ralentit les tests au lieu de les accélérer.

Préserver une configuration globale légère

Un fichier de configuration globale est pratique dans une grande base de code : il suffit d’enregistrer les mocks, polyfills et outils de test une seule fois, et chaque test les obtient automatiquement. Le problème, c’est que chaque fichier de test doit supporter tout cela, y compris ceux qui n’en ont pas besoin. Des imports lourds, des fixtures de base de données ou de gros registres de mocks dans setupFilesAfterEnv peuvent transformer des tests unitaires normalement rapides en tests lents.

Placer les configurations coûteuses plus près des tests qui en ont besoin : un outil d’aide importé explicitement, une fonction beforeAll dans le fichier correspondant, ou un projet Jest distinct avec sa propre configuration pour les tests d’intégration.

Réutiliser le cache

Les exécutions suivantes sont généralement plus rapides que les premières, car Jest met en cache les fichiers transformés ainsi que d’autres métadonnées. Vous le remarquerez surtout en mode surveillance, mais les pipelines CI en bénéficient également si le cache reste intact entre les exécutions. Dirigez cacheDirectory vers un chemin stable et conservez-le grâce à la fonction de mise en cache de votre système CI, en utilisant le fichier de verrouillage et la configuration de Jest comme clé, afin que chaque pipeline ne doive pas démarrer à zéro.

Utiliser le mode surveillance localement

Pour un travail local, jest --watch représente le meilleur mécanisme de boucle de rétroaction offert par Jest. Il ne relance que les tests liés aux fichiers modifiés, et son interface interactive vous permet de filtrer par nom de fichier ou motif de nom de test. Il n’est pas conçu pour les pipelines CI : un pipeline nécessite une seule exécution qui se termine par un code d’état, donc conservez le mode surveillance sur les machines des développeurs.

Activer isolatedModules pour TypeScript

Lorsque les tests TypeScript sont exécutés avec ts-jest, la vérification complète des types de chaque fichier entraîne une charge significative. Activer isolatedModules fait en sorte que le transformateur compile chaque fichier indépendamment, sans les informations de type provenant du reste du programme. Les équipes ont constaté des améliorations notables en termes de vitesse dans les projets Angular, et vous perdez très peu en sécurité tant que tsc --noEmit ou votre éditeur continue de vérifier les types du codebase. L’endroit exact où se trouve cette option dépend de la version de ts-jest que vous utilisez, il convient donc de consulter sa documentation actuelle.

Tester uniquement ce que modifie un changement

Il n’y a aucune raison d’exécuter l’ensemble du suite pour un changement qui ne concerne qu’un seul paquet. Jest lui-même permet de restreindre l’exécution avec --onlyChanged ou --changedSince=<branch>, outils qui utilisent le contrôle de version pour identifier les tests pertinents. Dans un monorepo, un système de construction comme Nx va encore plus loin en analysant le graphe du projet et en exécutant uniquement les tests des projets affectés par le changement actuel.

Gardez au moins une exécution complète quelque part, par exemple sur la branche principale ou en mode nocturne, afin de détecter tout ce que l’analyse des dépendances pourrait manquer.

Envisagez Vitest

Vitest est largement compatible avec l’API Jest, est activement maintenu, et fonctionne avec les frameworks JavaScript courants, y compris Nuxt. Pour les projets déjà construits avec Vite, c’est souvent le choix le plus naturel, et de nombreuses équipes l’optent en premier pour les nouveaux projets. La plupart des conseils mentionnés précédemment, tels que la mesure des performances, les limites des workers, une configuration simplifiée et l’exécution uniquement des tests concernés, s’appliquent tout aussi bien à Vitest. Si vous envisagez d’éliminer complètement un exécuteur tiers, consultez comment remplacer Jest par l’exécuteur de tests natif de Node.

Lorsque l’optimisation logicielle ne suffit plus

Finalement, aucun changement de configuration ne vaut un matériel plus rapide. Un ordinateur portable plus récent ou un exécuteur CI auto-hébergé de plus grande capacité peut représenter l’amélioration la moins coûteuse possible une fois que le jeu de tests lui-même est bien optimisé.

Points clés

  • Établissez une référence de base froide et non mémorisée, puis modifiez une chose à la fois.
  • Adaptez --maxWorkers ou --runInBand à la capacité réelle de chaque environnement.
  • Déplacez les configurations coûteuses hors des hooks globaux vers les tests qui en ont besoin.
  • Maintenez la mémoire tampon de Jest entre les exécutions CI ; utilisez uniquement le mode surveillance localement.
  • Laissez isolatedModules sauter les vérifications de type par fichier, tandis qu’une étape séparée avec tsc garantit la fiabilité des types.
  • Exécutez uniquement les tests concernés sur les branches fonctionnelles, et l’ensemble complet des tests sur la branche principale.