Allez directement au contenu principal

Test Unitaire React : Un Guide Pratique de bout en bout

Maîtrisez les tests unitaires React, de la mise en place à la CI/CD. Ce guide couvre Jest, RTL, hooks, async code, le mocking et les meilleures pratiques pour des applications cross-plateformes robustes.

Test Unit React : Guide Pratique De bout en bout

Vous faites une petite modification de l'interface utilisateur avant le déjeuner. Elle semble sans danger. L'étiquette d'un bouton change, une condition de rendu se simplifie et une fonctionnalité de hook récupère une nouvelle branch. La demande de tirage est propre, la revue est rapide et la mise à jour est déployée.

Une heure plus tard, le support signale que la connexion a cessé de fonctionner sur une plateforme. Web semble bien. Le shell de bureau a un chemin de rendu périmé. La build mobile se comporte différemment après une modification d'état asynchrone. Personne n'a remarqué cela car les code avaient des tests, mais pas les bons tests, et certainement pas un système fiable autour de ces tests.

C'est le principal problème avec le test unitaire de React dans les équipes de production. Écrire quelques tests qui passent n'est pas difficile. Construire un ensemble qui vous protège encore pendant les réorganisations, les trains de livraison, les correctifs chauds et la mise en paquet cross-plateforme est la partie difficile. Les applications React ne se cassent pas parce que l'équipe a oublié comment appeler render(). Elles se cassent parce que les tests dérivent vers les détails d'implémentation, le comportement asynchrone est recouvert et la CI traite le test comme un case à cocher au lieu d'une porte de mise en production.

Le test unitaire moderne de React fonctionne lorsque cela se comporte comme un système de sécurité. Feedback rapide localement. Contrôles déterministes dans la CI. Les limites claires autour de ce qui appartient à un test unitaire et ce qui ne l'appartient pas. Cela compte encore plus lorsque le même code React est déployé à travers les navigateurs, les Capacitor conteneurs ou les shells Electron.

Table des Matières

Pourquoi le test unitaire de React est votre meilleure protection

Les tests unitaires gagnent leur valeur lorsque ils détectent l'erreur que vous étiez convaincu ne pouvait pas se produire. Dans React, cela signifie généralement que le composant continue de s'afficher, mais le comportement dont les utilisateurs ont besoin a changé. Un bouton désactivé devient cliquable. Un état de chargement ne se déclenche jamais. Un message de rechange disparaît après une refacteur. Ces échecs sont petits en code et coûteux en production.

Le testing React a changé d'une manière importante lorsque Le testing React Library est devenu le modèle principal pour tester le comportement au lieu des internesEn poussant les équipes vers des tests qui reflètent le comportement utilisateur plutôt que les propriétés ou l'état des composants, comme le suggère la documentation de test de React Native. Résumé des tests React Native. Cette évolution compte car React code se réorganise constamment. Les hooks se déplacent. Les composants se séparent. Le contexte est introduit. Un test lié à la structure interne se brise lors de refacteurs sains. Un test lié au comportement visible survit généralement.

Ce que doit protéger un test unitaire

Un bon test unitaire React protège un petit contrat :

  • Sortie affichée : Voit l'utilisateur le bon texte, l'étiquette, l'état ou le fallback ?
  • Comportement d'interaction : La saisie, la sélection ou la modification change-t-elle l’UI correctement ?
  • Traitement des limites : Le composant se comporte-t-il correctement lorsqu'il reçoit les entrées attendues, les données manquantes ou un chemin d'erreur ?

Une faible protection protège la mauvaise chose :

  • Intégrales du composant : Forme de l'état, méthodes privées, propriétés d'implémentation uniquement
  • Mécanismes du framework : Même si React a mis à jour une fonctionnalité interne comme attendu.
  • Détails de l'enfant : Marquage détenus par les composants imbriqués que vous n'avez pas l'intention de vérifier ici

Règle pratique : Si vous pouvez réfacturer le composant sans changer ce que voit ou fait l'utilisateur, le test n'a pas besoin de changer non plus.

Les tests unitaires se situent également dans un système de test plus large. Ils ne visent pas à prouver que l'application fonctionne de bout en bout. Ils constituent la couche rapide qui attrape les régressions avant que vous n'ayez besoin d'un test de niveau navigateur ou d'une validation de niveau appareil. C'est pourquoi ils constituent la première ligne de défense dans n'importe quel empilement sensé de Tests automatiques pour les applications en production.

Pour les équipes React qui livrent souvent, la confiance provient de cette division du travail. Les tests unitaires détectent rapidement les régressions locales. Les tests d'intégration vérifient les articulations. Les tests finaux confirment les chemins critiques. Omettre la couche unitaire et tout ce qui est plus lent en aval doit supporter trop de poids.

Configuration de votre environnement de test React moderne

Un environnement de test fragile crée des tests flous avant même d'avoir écrit une seule assertion. Beaucoup de développeurs blâment Jest, jsdom ou React lorsque le problème sous-jacent est une configuration incohérente sur les machines locales et CI. La solution est de rendre l'environnement banal. Banal est bon ici.

Un espace de travail propre avec un moniteur d'ordinateur affichant les tests unitaires React code dans un éditeur code.

Démarrez avec un exécuteur et un environnement prévisibles

Pour une application React moderne, en particulier une créée avec Vite, la configuration de base devrait inclure :

  • Un exécuteur de tests : Jest reste commun, en particulier dans les anciens codebases React et les stacks CI d'entreprise.
  • Un environnement simulant un navigateur : jsdom les tests de composants rendent l'output DOM.
  • Utilités de Testing Library : @testing-library/react et @testing-library/jest-dom
  • Une seule entrée de configuration : Un seul fichier pour enregistrer les matcheurs et les mocks globaux

La clé de workflow que la guidance de test de React renforce est simple : rendre le composant dans un environnement jsdom, interroger l'interface utilisateur avec des sélecteurs comme getByText ou getByRole, déclencher l'interaction et vérifier le changement du DOM, comme décrit dans le Documentation de test ReactCette workflow reste fiable uniquement si chaque machine exécute le même environnement de test.

Une configuration Jest pratique ressemble généralement à ceci :

// jest.config.js
module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/src/setupTests.js'],
  moduleNameMapper: {
    '\\.(css|less|scss)$': 'identity-obj-proxy',
    '^@/(.*)$': '<rootDir>/src/$1',
  },
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
  },
};

If your team uses SWC instead of Babel, that’s fine. The point isn’t the transformer. The point is consistency. Choose one path and standardize it in the repo. If you want a good companion reference for broader JavaScript testing conventions, Capgo’s guide de tests unitaires en JavaScript est un document de transfert utile d'équipe.

Ajoutez le fichier de configuration dont votre suite dépendra.

Un bon setupTests.js économise beaucoup de bruit répétitif :

import '@testing-library/jest-dom';

Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(),
    removeListener: jest.fn(),
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
});

This file is where you solve environment gaps once instead of inside twenty test files. Add mocks for APIs your UI depends on, such as matchMedia, ResizeObserver, ou IntersectionObserver, si votre bibliothèque de composants les attend.

Sans cela, les développeurs patcheront les variables globales ad hoc. Cela crée des tests incohérents et des erreurs difficiles à suivre. Une personne peut faire passer son exécution locale car elle a ajouté un mock manuel dans un fichier. La CI échoue car la configuration n'a pas été partagée.

Maintenez le comportement local et CI alignés

La commande locale devrait correspondre à la commande CI le plus possible. Si les développeurs exécutent la commande watch avec des paramètres permissifs mais que la CI exécute une configuration plus stricte, vous obtiendrez des échecs inattendus après la fusion. Gardez les scripts explicites :

{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:ci": "jest --runInBand --coverage"
  }
}

Un court parcours aide les nouveaux membres de l'équipe à obtenir la même base rapidement :

The most impactful setup choice is discipline around defaults. Put aliases in config. Put environment mocks in one setup file. Use jsdom pour les tests de l'interface utilisateur et un environnement plus léger pour les utilitaires purs lorsque possible. Moins de comportement personnalisé que chaque test individuel nécessite, plus votre système devient fiable.

Écrire des Tests de Composants Significatifs

Les organisations n'ont pas de problème pour écrire des tests. Elles ont un problème pour écrire des tests qui comptent encore six mois plus tard.

Le modèle standard pour tester les composants React est toujours le bon : afficher le composant, interroger l'interface utilisateur avec des sélecteurs centrés sur l'utilisateur, déclencher une interaction et affirmer le changement de DOM résultantLes tests qui s'éloignent des détails d'implémentation comme l'état ou les props, comme décrit dans le Guide de test de ReactTester l'accordéon comme un utilisateur l'utilise

Testez l'accordion comme un utilisateur l'utilise

C'est suffisant pour plusieurs tests utiles : Accordion Le composant affiche un bouton avec un titre. Le contenu de la section débute caché. Lorsque l'on clique sur le bouton, le contenu est révélé et l'état d'accèsibilité est mis à jour.

Initial render shows the title but not the content.

  1. La première mise en page montre le titre mais pas le contenu.
  2. En cliquant sur le déclencheur, le contenu est révélé.
  3. En cliquant à nouveau, il se replie.
  4. Les attributs d'accessibilité reflètent l'état visible.

Cela est souvent négligé. Si votre composant utilise aria-expanded, aria-controlsLes meilleures tests de composants lisent comme un rapport de bogues que vous ne souhaitez jamais recevoir.

Les meilleures tests de composants ressemblent à un rapport de bug que vous n'aurez jamais.

Choisissez les requêtes en fonction de votre intention

La bibliothèque de test React vous offre plusieurs styles de requête, mais ils ne sont pas interchangeables. Choisissez le mauvais, vos tests deviennent bruyants ou trompeurs.

Type de requête Exemple d'utilisation Exemple d'utilisation Exemple d'utilisation
getBy Renvoie l'élément immédiatement Lance une erreur immédiatement Assurez-vous qu'un bouton ou un titre doit déjà être affiché sur l'écran
queryBy Renvoie l'élément immédiatement Renvoie null Assurez-vous que le contenu caché n'existe pas avant l'interaction
findBy Se résout lorsque l'élément apparaît Rejette après avoir attendu Assert async-loaded content appears after a fetch or delayed update

Un modèle mental simple aide :

  • Utilisez getBy pour les choses qui doivent déjà exister
  • Utilisez queryBy pour les choses qui ne doivent pas exister encore.
  • Utilisez findBy lorsque l'interface change ultérieurement.

Si un test commence par findBy Cela signifie généralement que l'auteur n'est pas sûr de la mise à jour du composant. Cela devient imprévisibilité plus tard.

Un exemple pratique d'accordéon

Voici un composant représentatif :

function Accordion({ title, children }) {
  const [open, setOpen] = React.useState(false);

  return (
    <section>
      <button
        aria-expanded={open}
        aria-controls="accordion-panel"
        onClick={() => setOpen(prev => !prev)}
      >
        {title}
      </button>
      {open ? (
        <div id="accordion-panel">
          {children}
        </div>
      ) : null}
    </section>
  );
}

Voici la forme des tests à conserver :

import { render, screen, fireEvent } from '@testing-library/react';

test('renders the accordion title and hides content initially', () => {
  render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);

  expect(screen.getByRole('button', { name: /shipping details/i })).toBeInTheDocument();
  expect(screen.queryByText(/delivery takes 3 days/i)).not.toBeInTheDocument();
});

test('reveals content when the trigger is clicked', () => {
  render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);

  fireEvent.click(screen.getByRole('button', { name: /shipping details/i }));

  expect(screen.getByText(/delivery takes 3 days/i)).toBeInTheDocument();
});

test('updates aria-expanded when opened', () => {
  render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);

  const button = screen.getByRole('button', { name: /shipping details/i });
  expect(button).toHaveAttribute('aria-expanded', 'false');

  fireEvent.click(button);

  expect(button).toHaveAttribute('aria-expanded', 'true');
});

Qu'est-ce qui manque est tout aussi important. Il n'y a pas d'affirmation contre l'état interne. Aucune vérification que setOpen était appelé. Pas de snapshot de l'ensemble de l'arbre rendu. Ces tests ajouteraient de la maintenance, pas de confiance.

Quelques habitudes renforcent les tests de composants :

  • Préférez les requêtes basées sur les rôles : Buttons, headings, dialogs, alerts, and inputs should usually be found by role.
  • Conservez chaque test étroit : Une seule comportement visible par test garde les échecs lisibles.
  • Nommez les tests en fonction des résultats : « Mettre à jour aria-expanded lors de l'ouverture » est beaucoup plus utile que « fonctionne correctement ».

Si un composant est difficile à tester à travers le DOM, cela révèle souvent un problème de conception. Peut-être cache-t-il l'état dans le mauvais endroit. Peut-être manque-t-il de balises de marquage sémantiques. Les bonnes tests poussent souvent les équipes vers de meilleurs composants.

Testez les Hooks personnalisés et la logique d'application

Les applications React cachent beaucoup de comportements importants en dehors des composants. Les transitions d'état vivent dans les hooks. La validation et la mise en forme vivent dans les fonctions d'aide. La mise en forme des données se produit souvent avant que quoi que ce soit ne soit affiché. Si vous n'avez que des composants visibles, vous manquerez une grande partie de la code qui peut toujours casser le comportement de production.

Les hooks nécessitent un harnais React-aware

Un hook personnalisé nécessite encore React pour s'exécuter correctement, testez-le donc avec renderHook et enveloppez les appels modifiant l'état dans act().

A petit useToggle Un petit crochet est un bon exemple :

import { useState, useCallback } from 'react';

export function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue);
  const toggle = useCallback(() => setValue(current => !current), []);
  return { value, toggle };
}

Son test devrait rester axé sur le contrat public :

import { renderHook, act } from '@testing-library/react';
import { useToggle } from './useToggle';

test('returns the initial value', () => {
  const { result } = renderHook(() => useToggle(true));
  expect(result.current.value).toBe(true);
});

test('toggles the value', () => {
  const { result } = renderHook(() => useToggle(false));

  act(() => {
    result.current.toggle();
  });

  expect(result.current.value).toBe(true);
});

Ce test est utile car le crochet lui-même est l'unité. Vous ne testez pas les internes de React. Vous vérifiez le comportement externe du crochet.

For product teams building reusable UI or feature primitives, this pattern matters a lot. Hooks often become the interface shared across apps, design systems, or internal tooling. If you’re designing reusable behavior with commercial intent, resources on Les hooks pour les produits des créateurs can help frame hooks as productized building blocks rather than just implementation details.

La logique devrait rester pure dans les tests

Tout n'a pas besoin jsdom, React, or Testing Library. If a function is pure, test it with plain Jest in a Node environment.

Example:

export function formatDisplayName(firstName: string, lastName: string) {
  return `${firstName.trim()} ${lastName.trim()}`.trim();
}

Le test est utile car le crochet est l'unité

import { formatDisplayName } from './formatDisplayName';

test('joins and trims both names', () => {
  expect(formatDisplayName(' Ada ', ' Lovelace ')).toBe('Ada Lovelace');
});

test('handles a missing last name', () => {
  expect(formatDisplayName('Ada', '')).toBe('Ada');
});

La victoire ici est la vitesse et la clarté. Lorsqu'une fonction n'a pas besoin d'un arbre rendu, ne lui donnez pas un arbre. Les outils spécifiques à React ajoutent un surcoût. Gardez les tests de logique métier petits, rapides et proches de la fonction qu'ils vérifient.

Une séparation pratique fonctionne bien :

  • Les Hooks : Utilisez renderHook, act()et les fournisseurs de wrapper lorsque nécessaire.
  • Les Utilitaires : Utilisez Jest simple et sans DOM.
  • La logique étatique transversale : Extrayez-la dans des aides testables lorsque le test du composant commence à faire trop.

Les équipes ont souvent surchargé les tests de composants de logique d'assertion qui appartiennent à une couche inférieure. L'extraction de cette logique donne deux avantages. Le test du composant devient plus propre, et le test de logique devient plus rapide.

Maîtriser les Techniques Avancées : Simuler et Async

La plupart des suites React peu fiables se cassent en deux endroits. Elles se cassent aux limites de dépendance, et elles se cassent autour du temps.

Pourquoi l'analyse et la simulation asynchrones constituent la ligne de démarcation entre un jeu de tests et un jeu de tests fiable avant la mise en production. Une analyse attribue 46,5 % des flottements de tests à des problèmes liés à l'environnement ou aux ressources, comme les temps d'exécution asynchrones en ce rapport d'analyse de tests unitaires ReactDans les applications React, cela correspond directement aux transitions d'état, au rendu différé, à l'interface utilisateur dérivée du réseau et aux tests qui supposent plutôt que d'attendre de manière déterministe.

Un tableau de comparaison montrant les techniques de test avancées de React, en mettant l'accent spécifiquement sur le mock des dépendances par rapport aux tests asynchrones.

Simulez la limite, pas chaque couche

La façon la plus rapide d'écrire un test trompeur est de simuler la moitié de votre arbre de composants et d'affirmer ensuite que vos propres simulations ont fonctionné.

Pour un composant qui récupère les données de compte, simulez le client de réseau ou le module API. N'ayez pas peur de simuler la fonction de crochet, le composant de ligne enfant, le chargeur de chargement et trois fonctions d'utilité, à moins que le test nécessite vraiment l'isolement à ces joints.

Utilisez ce jeu de règles :

  • Simulez les services externes : Les clients HTTP, les analyses, les API du navigateur uniquement, les ponts natifs
  • Simuler les API de plateforme instables : matchMedia, les timers, les interfaces de préchargement d'Electron, les plugins Capacitor lorsqu'ils sont indisponibles dans jsdom
  • Évitez de simuler vos propres internes par défaut : les hooks personnalisés, les enfants simples, les utilitaires locaux

Si un test passe car toutes les parties difficiles ont été remplacées par des faux, cela n'a pas grandement renforcé la confiance dans la mise en production.

Pour les équipes qui souhaitent des exemples et des modèles autour des API de l'exécuteur, Capgo les tutoriels de test est une bibliothèque de référence pratique, surtout lors de l'incorporation de développeurs qui connaissent React mais pas les mécaniques de test.

Async tests fail when timing is vague

Les échecs asynchrones proviennent généralement d'une des trois erreurs :

  1. Le test affirme trop tôt.
  2. Le test attend avec des temporisations arbitraires.
  3. Le composant se met à jour plus d'une fois, mais le test ne modèle qu'une seule transition.

Un test asynchrone stable a généralement cette forme :

test('shows user details after data loads', async () => {
  render(<UserProfile userId="42" />);
  expect(screen.getByText(/loading/i)).toBeInTheDocument();

  expect(await screen.findByText(/account owner/i)).toBeInTheDocument();
});

Ou, lorsque vous avez besoin de attendre une condition spécifique :

await waitFor(() => {
  expect(screen.getByRole('alert')).toBeInTheDocument();
});

Utilisez findBy Lorsque l'apparition d'un élément est l'événement dont vous vous souciez. Utilisez waitFor Lorsque la condition est plus large ou que l'état ne peut pas être exprimé avec une seule requête. Évitez setTimeout sauf si vous testez explicitement le comportement du chronomètre et utilisez des timers faux.

L'écosystème de test de React attend également que vous respectiez act() les sématiques autour des mises à jour. La bibliothèque de test gère beaucoup de cela pour vous, mais si vous avancez manuellement l'état ou les temporisateurs, vous devez encore réfléchir à quand les mises à jour se mettent à jour.

Sachez quelle outil de simulation à utiliser

Different outils de simulation résolvent différents problèmes :

Outil Best use Erreur commune
jest.fn() Appels de rappel ou fonctions injectées indépendants Utilisation pour remplacer un module entier lorsqu'un simple appel de rappel suffit
jest.spyOn() Observer ou surcharger une méthode sur un objet ou module réel Oublier de restaurer l'implémentation d'origine
jest.mock() Remplacer une dépendance de module à la frontière d'importation Simuler des modules importants par défaut et perdre du comportement significatif

Exemples d'aide :

  • Recherchez jest.fn() lorsqu'un composant prend un onSubmit attribut.
  • Utilisez jest.spyOn() lorsque vous avez besoin de vérifier console.error, une méthode de stockage ou une fonction API exportée.
  • Utilisez jest.mock() lorsqu'on importe un module qui aurait sinon heurté l'I/O, le code, ou le comportement en dehors de la frontière de l'unité.

Un domaine avancé que de nombreux guides négligent est la testabilité des chemins d'erreur dans React moderne. Les limites d'erreur, les changements d'état retardés et les UI de rechange asynchrones méritent des tests de premier ordre, et non seulement l'exemple de clic « heureux ». Si un enfant lance une erreur, assurez-vous que l'UI de rechange est visible. Si une requête échoue, assurez-vous que l'état de reprise visible est correct. Si un bouton est désactivé pendant le chargement, assurez-vous que c'est bien le cas. C'est là que se trouvent les bugs que les utilisateurs se rappellent.

Améliorer la qualité et la stratégie des tests

Beaucoup d'équipes poursuivent toujours la couverture comme si c'était la même chose que la confiance. Ce n'est pas le cas.

Vous pouvez atteindre un objectif de couverture et néanmoins manquer les régressions qui comptent. Un ensemble de déclarations d'assertion peu profondes, de captures d'écran larges et d'internes mockés créent l'apparence de la sécurité tout en augmentant le coût de maintenance.

Un infographic comparant les avantages de la testification de qualité par rapport à l'entretien coûteux de grands ensembles de tests.

La couverture est un plan, pas l'objectif

Les rapports de couverture sont utiles lorsqu'ils répondent à une question : quels chemins critiques n'ont pas encore de protection ?

Ils ne sont pas utiles lorsqu'ils poussent les développeurs à tester des enveloppes triviales, des marques de code statiques ou des fichiers de passage d'une ligne juste pour déplacer un pourcentage. Considérez la couverture comme un outil de découverte. Si l'état d'authentification, les actions de facturation, les drapeaux de fonctionnalité ou les invitations à mettre à jour n'ont pas de tests, c'est un signal. Si un composant d'icône présentatif n'a pas de tests, ce n'est généralement pas le cas.

Une bonne question de revue est simple : réduit-elle ce test le risque de publication ?

  • Oui : Il vérifie le comportement visible de l'utilisateur sur un chemin critique.
  • Peut-être : Il protège la logique métier qui est facile à briser lors d'une refacteur.
  • Non : Il affirme des détails d'implémentation ou duplique la valeur d'un autre test.

Ce que ne tester

Beaucoup de guides React ne passent pas suffisamment de temps sur l'omission. Cette lacune compte car la sur-mockage et la testabilité des détails d'implémentation créent des ensembles fragiles qui passent alors que l'expérience utilisateur continue de se briser, comme le note le guide de BrowserStack sur Ce que ne tester dans React.

Omittez ou limitez fortement ces modèles :

  • Affirmations d'état interne : N'implémentez pas isOpen les tests directs lorsque vous pouvez tester si le panneau s'est ouvert.
  • Comportement du framework : N'implémentez pas que React a appelé un effet. Testez le résultat de ce que l'effet change.
  • Intégration de bibliothèque tierce : Vérifiez votre intégration avec un sélecteur de date ou un navigateur, pas la logique de rendu de la bibliothèque.
  • Unités trop cassées : Si vous avez mocké tous les enfants et les assistants, vous ne testez peut-être plus un comportement significatif.

Les mauvais tests sont pires que les tests manquants lorsqu'ils bloquent les réfacteurs et ne parviennent pas à détecter les bogues de production.

Un bon heuristique est la propriété des limites. Testez ce que votre code possède. N'implémentez pas ce que React, le navigateur ou une bibliothèque mature possède déjà, à moins que votre couche d'intégration change le contrat.

Où les captures d'écran sont utiles et où elles nuisent

Snapshots aren’t useless. They’re just easy to misuse.

Utilisez-les avec parcimonie pour les composants avec une sortie stable et simple où une différence structurale large est significative. Évitez-les pour les composants interactifs ou dynamiques car ils deviennent du bruit. Les développeurs cessent de les lire et commencent à les mettre à jour de manière réflexe.

Mieux vaut souvent choisir des alternatives :

  • Pour la mise en condition, assurez la présence ou l'absence de texte clé.
  • Pour les changements d'état visuels, assurez le rôle, l'étiquette ou l'attribut qui compte.
  • Pour les erreurs et les fallbacks, assurez le message réel ou la région d'alerte.

Si votre équipe a besoin d'un processus qualité plus large au-delà des tests unitaires, un compagnon solide est un flux de garantie de qualité de l'application qui traite les tests, les contrôles de version et la planification de retrait comme un système. C'est le changement de mentalité qui améliore la qualité des tests le plus rapidement. Arrêtez de demander combien de tests vous avez. Démarrez à demander quelles défaillances pourraient encore atteindre les utilisateurs.

Intégration des Tests dans une Pipeline CI/CD Transverse de Plateforme

Un ensemble de tests qui ne s'exécute que sur un ordinateur de développeur est une suggestion, pas un contrôle.

L'ensemble devient opérationnel lorsque chaque demande de tirage exécute les mêmes vérifications dans un environnement propre et bloque les mises à jour lorsque ces vérifications échouent. Cela semble évident, mais de nombreuses équipes laissent encore des lacunes critiques. Les tests sont exécutés manuellement. Les rapports de couverture sont optionnels. Les tâches de packaging et de versionnement commencent avant que les tâches de test n'aient fini. C'est ainsi que les petites régressions d'interface glissent dans les échecs de version plus importants.

Avec un diagramme en cinq étapes illustrant le processus d'intégration des tests automatisés React dans une chaîne de développement CI/CD.

Une demande de tirage devrait déclencher le même contrôle chaque fois.

Pour tester unitairement React comme un filet de sécurité, le CI nécessite quelques éléments essentiels.

  • Exécuter sur chaque demande de tirage.
  • Install dependencies from lockfile
  • Utiliser la même commande de test chaque fois.
  • Échouer rapidement en cas de failures de test.
  • Publish artifacts only after tests pass

C'est le cœur des pratiques de déploiement continu pour les équipes d'applications.Construire la confiance avant la mise en production, pas après.

Un workflow d'Actions GitHub simple est suffisant pour de nombreuses équipes :

name: test

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  react-tests:
    runs-on: ubuntu-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v4

      - name: Set up Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Run unit tests
        run: npm run test:ci

C'est simple, et c'est ainsi que cela devrait être. Les pipelines les plus solides sont souvent les moins surprenants.

Pourquoi cela compte plus pour Capacitor et Electron

Cross-platform React apps carry more release risk than browser-only apps because the same UI code often ships in different containers with different runtime assumptions.

Un quelques exemples montrent où les pipelines sont utiles :

  • Capacitor applications : Le web code peut fonctionner localement mais échouer lorsqu'un pont de plugin, un état hors ligne ou un cas d'échappement du cycle d'application modifie le comportement après la mise en boîte.
  • Electron applications : Un composant de rendu peut dépendre d'API de préchargement, de messages de fenêtre ou d'état de bureau qui n'existeront pas en test de navigateur ordinaire à moins d'avoir été intentionnellement mockés.
  • Trains de publication partagés : Un bundle mauvais peut avoir un impact sur plusieurs cibles si votre processus de déploiement ne bloque pas étroitement la publication.

C'est pourquoi les tests unitaires devraient s'exécuter avant les tâches de packaging, et les tâches de packaging devraient s'exécuter avant les tâches de distribution. Chaque étape réduit le risque. Les tests unitaires détectent rapidement les régressions locales. Les tâches de packaging de plateforme vérifient les hypothèses d'environnement. L'approbation manuelle ou la mise en production étalée gère la confiance finale de la mise à jour.

Un workflow pratique d'Actions GitHub

Une pipeline plus mature divise généralement les responsabilités :

  1. Test : Tests unitaires rapides et de houlette
  2. Build : La mise en production uniquement après passage des tests
  3. Package : Capacitor synchronisation, packaging Electron ou bundling d'artefacts
  4. Release : Publiez uniquement à partir de branches ou de balises approuvées

Pour les équipes qui délivrent des mises à jour live à Capacitor ou Electron, c'est là que les outils de publication sont essentiels. Une option dans ce workflow est Capgoqui publie des bundles web signés pour les applications CapacitorJS et Electron avec prise en charge de rollback et de contrôle de lancement par canal. En pratique, cela signifie que votre job de test React peut agir comme la première barrière dure avant que tout bundle web ne soit promu vers la livraison de production ou de staging.

La règle opérationnelle est simple. N'allez pas laisser l'infrastructure de mise en production compenser les tests faibles. Utilisez l'infrastructure de mise en production après que les tests fiables ont déjà éliminé les mauvaises modifications.

Un système de test fiable change le comportement de l'équipe. Les ingénieurs se mélangent avec moins de hésitation. Les réviseurs se concentrent sur les cas d'extrémité au lieu de re-réexécuter les bases manuellement. Les gestionnaires de mise en production cessent de traiter chaque déploiement comme un jeu d'hasard. C'est le résultat de faire des tests unitaires React bien.


Si votre équipe déploye React via Capacitor ou Electron, la sécurité de la mise en production dépend de plus que des tests locaux réussis. Capgo offre aux équipes une façon contrôlée de publier des mises à jour web signées, de cibler les canaux de déploiement, et de revenir sur les mauvaises ensembles sans attendre la revue du magasin, ce qui convient naturellement derrière une chaîne d'intégration qui exige déjà que les tests unitaires passent avant le déploiement.

Mises à jour instantanées pour les applications Capacitor

When a web-layer bug is live, ship the fix through Capgo instead of waiting days for app store approval. Users get the update in the background while native changes stay in the normal review path.

un soutien humain de Martin

Démarrer maintenant

Dernières actualités de notre Blog

Capgo vous offre les meilleures informations nécessaires pour créer une application mobile véritablement professionnelle.