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 prend une nouvelle branchée. La demande de tirage est propre, la revue est rapide, et le déploiement est effectué.
Une heure plus tard, le support signale que la connexion a cessé de fonctionner sur une plateforme. Le Web semble normal. La coquille du bureau de bureau a un chemin de rendu périmé. La version 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.
Le principal problème avec la mise en œuvre de tests unitaires React dans les équipes de production est le suivant. Écrire quelques tests qui passent n'est pas difficile. Construire un ensemble qui vous protège encore pendant les révisions, les trains de lancement, les correctifs chauds et la mise en boîte de plusieurs plateformes est la partie difficile. Les applications React ne tombent pas en panne parce que l'équipe a oublié comment appeler render()Elles échouent parce que les tests se dirigent vers les détails d'implémentation, le comportement asynchrone est recouvert et la CI traite le test comme une case à cocher au lieu d'une porte de lancement.
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 envoyé à travers les navigateurs, Capacitor les conteneurs ou les coques d'Electron.
Table des matières
- Pourquoi le test unitaire React est votre meilleure sécurité
- Configurer votre environnement de test React moderne
- Écrire des tests de composants significatifs
- Testez des Hooks personnalisés et de la logique d'application
- Maîtriser les techniques avancées : simulation et asynchrone
- Améliorer la qualité et la stratégie des tests
- Intégration des tests dans une chaîne de production CI/CD cross-plateforme
Pourquoi les tests unitaires de React constituent votre meilleure protection
Les tests unitaires gagnent leur salaire 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ébloque jamais. Un message de remplacement disparaît après une refacteur. Ces erreurs sont petites dans code et coûteuses en production.
Le testing React a changé d'une manière importante lorsque La bibliothèque de testing React est devenue le modèle principal pour tester le comportement au lieu des internes, poussant les équipes vers des tests qui reflètent le comportement de l'utilisateur plutôt que les propriétés ou l'état des composants, comme le montre la documentation de testing de React Native à Vue d'ensemble de la testing de React Native. Cette évolution compte car les composants React code sont constamment réorganisés. Les hooks se déplacent. Les composants se divisent. Le contexte est introduit. Un test lié à la structure interne se brise pendant des refacteurs sains. Un test lié au comportement visible survit généralement.
Quel est l'objectif d'un test unitaire ?
Un bon test unitaire React protège une petite convention :
- Sortie de rendu : Le utilisateur voit-il le bon texte, l'étiquette, l'état ou le fallback ?
- Comportement d'interaction : Clique, saisie ou basculement changent-ils la UI correctement ?
- Gestion des limites : Le composant se comporte-t-il correctement lorsqu'il reçoit les entrées attendues, les données manquantes ou une voie d'erreur ?
Un test faible protège la mauvaise chose :
- Intégrales du composant : Forme de l'état, méthodes privées, props d'implémentation uniquement
- Mécanismes du framework : Quel est le comportement réel de React lors de la mise à jour d'une fonctionnalité interne ?
- Détails de l'enfant : La mise en forme appartenant aux composants imbriqués que vous n'avez pas l'intention de vérifier ici
Règle pratique : Si vous pouvez réorganiser le composant sans changer ce que voit ou fait l'utilisateur, le test ne devrait pas non plus changer.
Les tests unitaires s'intègrent é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 détecte les régressions avant que vous ne nécessitiez un test au niveau du navigateur ou une validation au niveau du dispositif. C'est pourquoi ils constituent la première ligne de défense dans n'importe quel empilement sensé de tests automatisés pour les applications de 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 joints. Les tests end-to-end confirment les chemins critiques. Omettre la couche unitaire et tout ce qui est plus lent en aval doit supporter un poids trop important..
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 __CAPGO_KEEP_0__ dans un __CAPGO_KEEP_1__ éditeur.

__CAPGO_KEEP_0__
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 :
jsdompour que les tests de composants puissent rendre une sortie DOM. - Les utilitaires de la bibliothèque de testing :
@testing-library/reactet@testing-library/jest-dom - Un point d'entrée de configuration unique : Un seul fichier pour enregistrer les matcheurs et les mocks mondiaux.
La clé de la guidance de testing de React est simple : rendre le composant dans un environnement jsdom, interroger l'interface utilisateur avec des sélecteurs comme getByText ou getByRole, déclencher une interaction et affirmer le changement de la sortie DOM, comme décrit dans le Documentation de test ReactCe flux de travail reste fiable que si chaque machine exécute le même environnement de test.
Un setup 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',
},
};
Si votre équipe utilise SWC au lieu de Babel, cela ne pose pas de problème. Le point n'est pas le transformateur. Le point est la cohérence. Choisissez une voie et standardisez-la dans le dépôt. Si vous souhaitez une référence complémentaire utile pour les conventions de test JavaScript plus larges, le guide des tests unitaires de Capgo est un document de transfert d'équipe utile. Ajoutez le fichier de configuration que votre ensemble de tests dépendra.
Un setup approprié
économise beaucoup de bruit répétitif : setupTests.js Ce fichier est où vous résolvez les écarts d'environnement une fois au lieu de les résoudre à l'intérieur de vingt fichiers de test. Ajoutez des mocks pour les API que votre bibliothèque UI dépend, telles que
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(),
})),
});
ou matchMedia, ResizeObserversi votre bibliothèque de composants s'y attend. IntersectionObserverDocumentation de test React
Sans cela, les développeurs patchent les globaux ad hoc. Cela crée des tests incohérents et des échecs difficiles à suivre. La passe locale d'une personne passe parce qu'ils ont ajouté un mock manuel dans un fichier. Le CI échoue parce que le setup n'a pas été partagé.
Maintenez le comportement local et CI aligné
Le command local devrait correspondre au command CI le plus possible. Si les développeurs exécutent la commande watch avec des paramètres permissifs mais que le 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 :
La plus grande décision d'installation est la discipline autour des paramètres par défaut. Mettez les alias dans la configuration. Mettez les mocks d'environnement dans un fichier de configuration. Utilisez jsdom pour les tests UI 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 ont encore de l'importance six mois plus tard.
Le modèle standard pour les tests unitaires des 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 DOM résultantqui maintient les tests à l'écart des détails d'implémentation comme l'état ou les props, comme décrit dans le guide de test React. La clé est d'appliquer ce modèle avec modération.
Testez l'accordéon comme un utilisateur l'utilise
Prenez un composant de base. Il affiche un bouton avec un titre. Le contenu du panneau commence caché. Cliquez sur le bouton pour révéler le contenu et mettre à jour l'état d'accessibilité. Accordion Cela suffit pour plusieurs tests utiles :
La première rendu affiche le titre mais pas le contenu.
- Cliquez sur le déclencheur pour révéler le contenu.
- Cliquez à nouveau pour le faire reculer.
- Les attributs d'accessibilité reflètent l'état visible.
- Ce dernier point est souvent négligé. Si votre composant utilise aria- ou role-based structure, vérifiez-les. Ce ne sont pas des détails d'implémentation. C'est partie de la convention utilisateur.
Les meilleures tests de composants lisent comme un rapport de bug que vous n'aurez jamais envie de recevoir. aria-expanded, aria-controls__CAPGO_KEEP_0__
__CAPGO_KEEP_1__
Choisissez les requêtes en fonction de l'intention
La bibliothèque de test React vous offre plusieurs styles de requêtes, mais ils ne sont pas interchangeables. Le choix du mauvais style rend les tests bruyants ou trompeurs.
| Type de requête | Lorsque l'élément est trouvé | Lorsque l'élément n'est pas trouvé | Exemple d'utilisation |
|---|---|---|---|
getBy |
Renvoie l'élément immédiatement | Jette une erreur immédiatement | Assurez-vous que le bouton ou l'en-tête 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 |
Résout lorsque l'élément apparaît | Rejette après avoir attendu | Asserter que le contenu chargé en mode asynchrone apparaît après une requête ou une mise à jour retardée |
Un modèle mental simple aide :
- Utilisez
getBypour les choses qui doivent déjà exister. - Utilisez
queryBypour les choses qui ne doivent pas exister encore. - Utilisez
findBylorsque les modifications de l'interface utilisateur ont lieu plus tard.
Si un test commence par findBy pour tout, cela signifie généralement que l'auteur n'est pas sûr de quand le composant se met à jour. Cette incertitude devient ensuite de la flousserie ultérieurement.
Un exemple d'accordéon pratique
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>
);
}
Et voici la forme des tests qui valent la peine de 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');
});
Ce qui manque est tout aussi important. Il n'y a pas d'assertion contre l'état interne. Pas de vérification de ce qui a été appelé. Pas de snapshot de l'arbre rendu entier. Ces tests ajouteraient de la maintenance, pas de confiance. setOpen Un certain nombre de habitudes rendent les tests de composants plus solides :
Préférez les requêtes basées sur le rôle :
- Les boutons, les titres, les dialogues, les avertissements et les champs de saisie devraient généralement être trouvés par rôle. Gardez chaque test étroit :
- Un comportement visible par l'utilisateur par test garde les erreurs lisibles. Nommez les tests après les résultats :
- “met à jour aria-expanded lors de l'ouverture” est beaucoup plus utile que “fonctionne correctement.” A few habits make component tests stronger:__CAPGO_KEEP_0__
If un test un composant est difficile à tester à travers le DOM, cela révèle souvent un problème de conception. Peut-être qu'il cache l'état dans le mauvais endroit. Peut-être qu'il manque de balises de sens. Les bonnes tests poussent souvent les équipes vers de meilleurs composants.
Testez les crochets personnalisés et la logique d'application
Les applications React cachent beaucoup de comportement important en dehors des composants. Les transitions d'état vivent dans les crochets. 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 s'affiche. 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 crochets ont besoin d'un harnais React-aware
Un crochet personnalisé a toujours besoin de React pour s'exécuter correctement, alors testez-le avec renderHook et enveloppez les appels modifiant l'état dans act().
Un petit useToggle 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 doit 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 n'êtes pas en train de tester les internes de React. Vous vérifiez le comportement externe du crochet.
Pour les équipes de produits créant des UI ou des primitives de fonctionnalités réutilisables, ce modèle compte beaucoup. Les crochets deviennent souvent l'interface partagée entre les applications, les systèmes de conception ou les outils internes. Si vous concevez un comportement réutilisable avec une intention commerciale, consultez les ressources sur les crochets pour les produits de créateurs peut aider à considérer les appels de fonctions comme des blocs de construction standardisés plutôt que comme des détails d'implémentation.
La logique pure doit rester pure dans les tests
Ce n'est pas nécessaire pour tout jsdom, React, ou Testing Library. Si une fonction est pure, testez-la avec Jest simple dans un environnement Node.
Exemple :
export function formatDisplayName(firstName: string, lastName: string) {
return `${firstName.trim()} ${lastName.trim()}`.trim();
}
Ce test devrait être simple comme la mort :
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 de rendu, ne lui en donne pas. Les outils spécifiques à React ajoutent un surcoût. Conservez les tests de logique métier petits, rapides et proches de la fonction qu'ils vérifient.
Un split pratique fonctionne bien :
- Appels de fonctions : Utilisez
renderHook,act(), et les fournisseurs de wrapper lorsque nécessaire. - Utilités : Utilisez Jest simple et sans DOM.
- Logique transversale étatique : Insérez-le dans des aides testables lorsque le test du composant commence à faire trop de choses.
Les équipes ajoutent souvent trop de logique de test dans les tests de composant avec des assertions qui appartiennent à une couche inférieure. En sortant cette logique, vous obtenez deux avantages. Le test du composant devient plus propre, et le test de logique devient plus rapide.
Maîtriser les techniques avancées : Mocking et Async
La plupart des suites de tests React les plus instables se cassent en deux endroits. Ils se cassent aux limites de dépendance, et ils se cassent autour du temps.
C'est pourquoi le test asynchrone et le mocking sont la ligne de démarcation entre une suite de tests de jouet et une que vous pouvez vous fier avant la mise en production. Une analyse attribue 46,5 % de la flottabilité des tests aux problèmes liés à l'environnement ou aux ressources, comme les temps d'attente asynchrones dans ce rapport d'analyse de tests React unitaires. Dans les applications React, cela se traduit directement par les transitions d'état, le rendu retardé, l'interface utilisateur dérivée du réseau et les tests qui supposent au lieu de attendre de manière déterministe.

Simulez les limites, pas chaque couche
La façon la plus rapide d'écrire un test trompeur est de simuler la moitié de votre arbre de composant et d'affirmer ensuite que vos propres simulations ont fonctionné.
Pour un composant qui récupère des données de compte, simulez le client de réseau ou le module API. N'ayez pas peur de simuler l'appel à l'API, les hooks, les composants enfants, les indicateurs de chargement et les trois fonctions d'utilitaire, à moins que le test nécessite vraiment une isolation à ces points de jonction.
Utilisez ce jeu de règles :
- Simulez les services externes : Les clients HTTP, les analyses, les API du navigateur uniquement, les ponts natifs
- Simulez les API de plateforme instables :
matchMediaLes temporisateurs, les interfaces de préchargement Electron, les plugins Capacitor lorsqu'ils ne sont pas disponibles 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 parce que toutes les parties difficiles ont été remplacées par des faux, il n'a pas beaucoup acheté de confiance dans la libération.
Pour les équipes qui veulent des exemples et des modèles autour des API de l'exécuteur, Capgo tutoriels de test est une bibliothèque de référence pratique, en particulier lors de l'inscription des développeurs qui connaissent React mais pas encore les mécanismes de test.
Les tests asynchrones échouent lorsqu'il y a un timing vague
Les échecs asynchrones proviennent généralement d'une des trois erreurs suivantes :
- L'assertion du test se produit trop tôt.
- Le test attend avec des temporisations arbitraires.
- Le composant se met à jour plus d'une fois, mais le test ne modélise 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 d'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 In tests, à moins que vous ne testiez explicitement le comportement du chronomètre et que vous utilisiez des temporisations artificielles.
L'écosystème de test de React attend également que vous respectiez les act() Les sémiotiques autour des mises à jour. La bibliothèque de test gère une grande partie de cela pour vous, mais si vous avancez manuellement l'état ou les temporisations, vous devez encore réfléchir à quand les mises à jour se mettent à jour.
Connaissez lequel de ces outils de simulation à utiliser
Different les outils de simulation résolvent différents problèmes :
| Outil | Meilleur usage | Erreur commune |
|---|---|---|
jest.fn() |
Appels de rappel faux ou fonctions injectées | Utiliser pour remplacer un module entier lorsqu'un rappel simple suffit |
jest.spyOn() |
Observer ou remplacer une méthode sur un objet ou un module réel | Oublier de restaurer l'implémentation d'origine |
jest.mock() |
Remplacez une dépendance de module à la limite de l'importation | La mise en miroir de modules importants par défaut et la perte de comportement significatif |
Les exemples d'aide :
- Soyez à l'écoute de
jest.fn()lorsqu'un composant prend unonSubmitattribut. - Utilisez
jest.spyOn()lorsque vous avez besoin de vérifierconsole.error, une méthode de stockage ou une fonction API exportée. - Utilisez
jest.mock()lorsque l'importation d'un module aurait sinon un impact sur l'E/S, le code natif code ou le comportement en dehors de la limite de test unitaire.
Un domaine avancé que de nombreux guides négligent est la mise en test de la voie d'erreur dans React moderne. Les limites d'erreur, les changements de l'état retardés et les UI de fallback asynchrones méritent des tests de premier ordre, pas seulement l'exemple de clic « heureux ». Si un enfant lance une erreur, affirmez l'UI de fallback. Si une requête échoue, affirmez l'état de récupération visible. Si un bouton est désactivé pendant le chargement, affirmez aussi cela. Ce sont les bogues que les utilisateurs se rappellent.
Améliorer la qualité et la stratégie de test
Beaucoup d'équipes poursuivent encore la couverture comme si c'était la même chose que la confiance. Ce n'est pas le cas.
On peut atteindre un objectif de couverture et néanmoins manquer les régressions qui comptent. Un ensemble complet d'assertions superficielles, de captures d'écran larges et d'internes mockés crée l'apparence de sécurité tout en augmentant les coûts de maintenance.

La couverture est une carte, pas le but
Les rapports de couverture sont utiles lorsqu'ils répondent à une seule 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, du markup statique ou des fichiers de passage d'une ligne juste pour déplacer un pourcentage. Traitez 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ésentationnel n'a pas de tests, ce n'est généralement pas le cas.
Une question de revue saine est simple : cette test réduit-t-il le risque de lancement ?
- Oui : Elle vérifie le comportement visible de l'utilisateur sur un chemin critique.
- Peut-être : Elle protège la logique métier qui est facile à briser lors d'une refacturation.
- No : Ce test 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 le sur-mockage et les tests d'implémentation détaillés créent des ensembles fragiles qui passent les tests alors que l'expérience utilisateur se brise, comme le note le guide de BrowserStack sur ce que ne tester dans React.
Omettez ou limitez fortement ces modèles :
- L'assertion d'état interne : N'ayez pas peur de ne pas
isOpentester directement lorsque vous pouvez tester si le panneau s'est ouvert. - Le comportement du framework : N'ayez pas peur de ne pas
- tester que React a appelé un effet. Testez le résultat de ce que l'effet change. Testez votre intégration avec un sélecteur de date ou un routeur, pas la logique de rendu de la bibliothèque elle-même.
- Unités trop fragmentées : Si vous avez simulé tous les enfants et les assistants, vous ne testez peut-être plus un comportement significatif.
Les mauvaises 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'essayez pas de tester ce que React, le navigateur ou une bibliothèque mature possèdent, à moins que votre couche d'intégration change le contrat.
Où les snapshots sont utiles et où ils nuisent
Les snapshots ne sont pas inutiles. Ils sont juste faciles à mal utiliser.
Utilisez-les parcimonieusement pour les composants avec une sortie stable et simple où une large différence structurale 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.
Des alternatives meilleures existent généralement :
- Pour la rendu conditionnel, assurez-vous de la présence ou de l'absence de texte clé.
- Pour les changements d'état visuels, assurez-vous du rôle, de l'étiquette ou de l'attribut qui compte.
- Pour les erreurs et les fallbacks, assurez-vous du message ou de la région d'alerte réel.
If votre équipe a besoin d'un processus qualité plus large que les tests unitaires, un partenaire solide est un flux de garantie de qualité d'application qui traite les tests, les contrôles de mise en production et la planification de reversion comme un système unique. C'est le changement d'attitude qui améliore la qualité des tests le plus rapidement. Arrêtez de demander combien de tests vous avez. Commencez à demander quelles erreurs pourraient encore atteindre les utilisateurs. Intégrer les Tests dans une Chaîne de Production Continu (CI/CD) Multiformat Un ensemble de tests qui ne s'exécute que sur un ordinateur de développement est une suggestion, pas un contrôle.
Le jeu devient opérationnel lorsque chaque demande de tirage exécute les mêmes vérifications dans un environnement propre et bloque les mises en merge 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 mise en production commencent avant que les tâches de test n'aient terminé. C'est ainsi que les petites régressions d'interface peuvent s'introduire dans des échecs de mise en production plus importants.
Un diagramme de flux à 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

Exécuter sur chaque demande de tirage
Installer les dépendances à partir du fichier de verrouillage
- Utiliser le même commandement de test chaque fois
- Intégrer les Tests dans une Chaîne de Production Continu (CI/CD) Multiformat
- Un ensemble de tests qui ne s'exécute que sur un ordinateur de développement est une suggestion, pas un contrôle.
- Échouez rapidement en cas de failures de test
- Publiez uniquement les artefacts après que les tests passent
C'est le cœur de pratiques de déploiement continu pour les équipes d'applications. Construisez la confiance avant la mise en production, et non après.
A simple GitHub Actions workflow is enough for many teams:
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
Cela n'est pas élégant, et c'est l'idée. Les pipelines les plus solides sont généralement les moins surprenants.
Why this matters more for Capacitor and 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 apps: Web code may pass locally but fail when a plugin bridge, offline state, or app lifecycle edge case changes behavior after packaging.
- Applications Electron: Un composant de rendu peut dépendre d'APIs de préchargement, de messages de fenêtre ou d'état de bureau uniquement qui n'existeront pas dans des tests de navigateur classiques à moins d'être simulés intentionnellement.
- Trains de publication partagés: Une mauvaise archive 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 doivent s'exécuter avant les tâches de packaging, et les tâches de packaging doivent 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. La vérification de packaging de plateforme vérifie les hypothèses d'environnement. L'approbation manuelle ou la mise en production étalée gère la confiance finale.
Un workflow d'Actions pratique GitHub
Un pipeline plus mature divise généralement les responsabilités:
- Tâche de test: Tests unitaires rapides et de crochet
- Tâche de construction: Construction de production uniquement après que les tests passent
- Tâche de packaging: Capacitor synchronisation, packaging d'Electron ou regroupement d'artefacts
- Job de publication : Publiez uniquement à partir de branches ou de tags approuvés
Pour les équipes qui livrent des mises à jour en direct à Capacitor ou des applications Electron, c'est là que les outils de publication sont importants. Une option dans ce flux de travail est Capacitor CapgoPubliez des ensembles de web signés pour les applications CapacitorJS et Electron avec prise en charge de la mise en annuler et des contrôles de lancement basés sur les canaux. En pratique, cela signifie que votre job de test React peut agir comme la première barrière dure avant que tout ensemble de web ne soit promu vers la livraison de production ou de mise en ligne.
La règle opérationnelle est simple. N'obligez pas l'infrastructure de publication à compenser les tests faibles. Utilisez l'infrastructure de publication après que les tests fiables aient déjà éliminé les changements mauvais.
Un système de test fiable change le comportement de l'équipe. Les ingénieurs fusionnent avec moins de hésitation. Les réviseurs se concentrent sur les cas d'extrémité au lieu de réexécuter les bases manuellement. Les gestionnaires de publication ne traitent plus chaque déploiement comme un jeu d'hasard. C'est le résultat de faire des tests unitaires React bien.
Si votre équipe livre React à travers Capacitor ou Electron, la sécurité de la publication dépend de plus que des tests locaux verts. Capgo __CAPGO_KEEP_0__ donne aux équipes un moyen contrôlé de publier des mises à jour de web signées, de cibler les canaux de lancement et de remonter les ensembles de web mauvais sans attendre la revue de la boutique, ce qui convient naturellement derrière une chaîne de pipeline CI qui exige déjà que les tests unitaires passent avant la déployment.