Vous faites une petite modification de l'interface utilisateur avant le déjeuner. Elle semble sans danger. L'étiquette d'un bouton change, une rendu conditionnel se simplifie, et un hook d'aide prend une nouvelle branch. 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 s'est arrêtée sur une plateforme. Le Web semble normal. La coquille du bureau de bureau a un chemin de rendu périmé. La construction mobile se comporte différemment après un changement 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 les tests unitaires de 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 livraison, les correctifs chauds et la mise en paquet cross-plateforme 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 dérivent vers les détails d'implémentation, le comportement asynchrone est recouvert et la CI traite les tests comme un case à cocher au lieu d'une porte de livraison.
Les tests unitaires modernes de React fonctionnent 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, Capacitor conteneurs ou les coques Electron.
Table des matières
- Pourquoi les tests unitaires de React constituent votre meilleure sécurité
- Configuration de 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 un pipeline CI/CD cross-plateforme
Pourquoi le test unitaire de React est votre meilleure protection
Les tests unitaires gagnent leur pain quand ils détectent l'erreur que vous étiez confiant ne pourrait 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 test React a changé de manière importante quand React Testing Library est devenu 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 test de React Native à Vue d'ensemble des tests de React Native. Cette évolution compte car les composants React code sont constamment réorganisés. 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.
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, des 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écaniques du framework : Whether React a mis à jour un crochet de manière exacte comme vous l'attendiez internement
- 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 refacturer le composant sans changer ce que voit ou fait l'utilisateur, le test ne devrait pas non plus changer.
Les tests unitaires s'assoient également dans un système de test plus large. Ils ne cherchent pas à prouver que l'application fonctionne de bout en bout. Ils sont la couche rapide qui attrape les régressions avant que vous n'ayez besoin d'un test au niveau du navigateur ou d'une validation au niveau du dispositif. C'est pourquoi ils sont la première ligne de défense dans n'importe quel empilement sensé de test automatique pour les applications de production.
Pour les équipes React qui expédient souvent, la confiance vient de cette division du travail. Les tests unitaires attrapent les régressions locales rapidement. Les tests d'intégration vérifient les joints. Les tests finaux confirment les chemins critiques. Omettre la couche unitaire et tout ce qui est plus lent en aval doit porter trop de poids.
Configuration de votre environnement de test React moderne
Un environnement de test fragile crée des tests flous avant même que vous n'ayez é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 ennuyeux. Ennuyeux est bon ici.

Commencez par un exécuteur prévisible et un environnement
For une application React moderne, en particulier une créée avec Vite, la configuration de base devrait inclure :
- Un exécuteur de tests : Jest reste courant, 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 la sortie DOM. - Les utilitaires de la bibliothèque de test :
@testing-library/reactet@testing-library/jest-dom - Un seul point d'entrée de configuration : Un fichier pour enregistrer les matcheurs et les mocks mondiaux
La clé de la guidance de test 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 uniquement 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 dans vingt fichiers de test. Ajoutez des mocks pour les API que votre bibliothèque UI attend, 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(),
})),
});
Cloudflare matchMedia, ResizeObserverCapacitor IntersectionObserverGitHub
Sans cela, les développeurs patchent les globaux ad hoc. Cela crée des tests incohérents et des échecs difficiles à suivre. La mise en œuvre locale passe car quelqu'un a ajouté un mock manuel dans un fichier. Le CI échoue car le setup n'a pas été partagé.
Maintenez le comportement local et CI aligné
La commande locale devrait correspondre à la commande CI aussi étroitement que 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 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'implémentation 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 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 ont encore de l'importance six mois plus tard.
Le modèle standard pour les tests unitaires des composants React est toujours le bon : rendez le composant, interrogez l'interface utilisateur avec des sélecteurs centrés sur l'utilisateur, déclenchez une interaction et affirmez la modification du DOM résultantequi 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. Le truc 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'accèsibilité. Accordion Cela suffit pour plusieurs tests utiles :
La première mise en page montre le titre mais pas le contenu.
- Cliquez sur le déclencheur pour révéler le contenu.
- Cliquez à nouveau pour le faire disparaître.
- Les attributs d'accèsibilité reflètent l'état visible.
- Ce dernier point est souvent négligé. Si votre composant utilise aria-*, ou une structure basée sur le rôle, vérifiez-les. Ce ne sont pas des détails d'implémentation. C'est une partie du contrat utilisateur.
Les meilleures tests de composants lisent comme un rapport de bogues que vous ne souhaitez jamais recevoir. aria-expanded, aria-controlsInitial render shows the title but not the content.
Clicking the trigger reveals the content.
Choisissez les requêtes en fonction de votre 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 | Lève 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 | Assurez-vous que le contenu chargé en parallèle apparaisse 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 flottabilité ultérieure.
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 à 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'ensemble de l'arbre rendu. Ces tests ajouteraient de la maintenance, pas de confiance. setOpen Quelques 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 alertes 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 échecs lisibles. Nommez les tests après les résultats :
- « Met à jour aria-expanded lors de l'ouverture » est beaucoup plus utile que « fonctionne correctement ». __CAPGO_KEEP_0__
If un component est difficile à tester à travers le DOM, cela révèle souvent un problème de conception. Peut-être qu'il cache l'état dans un endroit incorrect. 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 comportements importants 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, donc 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 des créateurs peut aider à présenter 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
Tout n'a pas besoin de 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();
}
Cette mise à l'épreuve 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');
});
Le gain 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 découpage 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 assistants de test lorsque le test du composant fait 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.
Maitriser les Techniques Avancées : Mocking et Async
La plupart des suites de tests React peu fiables 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 à des problèmes environnementaux ou liés aux ressources, tels que les temps d'attente asynchrones dans ce rapport d'analyse de tests React. 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 d'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 mocks 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 l'appel à l'API, le hook, la composante enfant, le chargeur de chargement et les trois fonctions d'utilité, à moins que le test nécessite vraiment l'isolement à ces points de jonction.
Utilisez ce jeu de règles :
- Simulez les services externes : Les clients HTTP, les analyses, les APIs du navigateur uniquement, les ponts natifs
- Simulez les APIs 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, cela n'a pas beaucoup acheté de confiance dans la mise en production.
Pour les équipes qui veulent des exemples et des modèles autour des API de l'exécuteur, Capgo tests de tutoriels s'agit d'une bibliothèque de référence pratique, notamment lors de l'inscription des développeurs qui connaissent React mais pas encore les mécanismes de test.
Les tests asynchrone échouent lorsque le temps est vague
Les échecs asynchrone proviennent généralement d'une des trois erreurs :
- 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ématiques 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 outils de simulation résolvent différents problèmes :
| Outil | Meilleur usage | Erreur commune |
|---|---|---|
jest.fn() |
Appels de rappel faux ou fonctions injectées en standalone | 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() |
Remplacer une dépendance de module à la frontière d'importation | Simuler de grandes modules par défaut et perdre un comportement significatif |
Exemples d'aide :
- Saisir
jest.fn()lorsqu'un composant prend unonSubmitpropriété. - Utiliser
jest.spyOn()lorsque vous avez besoin de vérifierconsole.errorune méthode de stockage ou une fonction exportée API. - Utiliser
jest.mock()lorsque l'importation d'un module aurait autrement atteint l'I/O, le code natif ou le comportement en dehors de la limite de l'unité.
L'une des zones avancées que de nombreux guides négligent est la testabilité des chemins 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 "happy path". 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 bugs que les utilisateurs se rappellent.
Améliorer la qualité et la stratégie de test
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 manquer encore les régressions qui comptent. Un ensemble complet d'assertions superficielles, de captures d'écran larges et d'internes mockés créent 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 question : quels chemins critiques n'ont pas encore de protection ?
Ils ne sont pas utiles lorsqu'ils poussent les développeurs à tester des wrappers triviaux, 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 : 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 pendant la refacturation.
- Non: Il affirme les détails d'implémentation ou duplique la valeur d'un autre test.
Ce que ne tester en unités
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 les tests alors que l'expérience utilisateur est toujours cassée, comme le note le guide de BrowserStack sur ce que ne tester en unités dans React.
Omettez ou limitez fortement ces modèles :
- Les affirmations d'état interne : N'essayez pas de
isOpentester directement lorsque vous pouvez tester si le panneau s'est ouvert. - Le comportement du framework : N'essayez pas de
- 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.
- Unités brisées : Si vous avez mocké tous les enfants et les helpers, 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 indicateur 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 ne change le contrat.
Où les captures d'écran sont utiles et où elles nuisent
Les captures d'écran ne sont pas inutiles. Elles sont juste faciles à mal utiliser.
Utilisez-les avec parcimonie 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 quels échecs pourraient encore atteindre les utilisateurs. Intégrer les Tests dans un Pipeline CI/CD Cross-Plateforme 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 beaucoup d'é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 fini. C'est ainsi que les petites regressions d'interface utilisateur glissent dans les é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 un pipeline de développement CI/CD.
Une demande de tirage devrait déclencher le même barrage chaque fois

Exécuter sur chaque demande de tirage
Installer les dépendances à partir du fichier de verrouillage
- Utiliser la même commande de test chaque fois
- Intégrer les Tests dans un Pipeline CI/CD Cross-Plateforme
- Un ensemble de tests qui ne s'exécute que sur un ordinateur de développement est une suggestion, pas un contrôle.
- Faillez rapidement en cas de failures de test
- Publiez les artefacts uniquement 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 justement le point. 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.
A 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'API 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 la plateforme vérifie les hypothèses d'environnement. L'approbation manuelle ou la mise en production étalée gère la confiance finale dans la mise en production.
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
- Lancement de job : Publiez uniquement à partir de branches ou de balises approuvées
Pour les équipes qui délivrent des mises à jour en direct à Capacitor ou Electron, c'est là que les outils de lancement sont importants. Une option dans ce flux de travail est Capgo, qui publie des bundles web signés pour les applications CapacitorJS et Electron avec des contrôles de rollback et de mise en production basés sur des canaux. 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 mise en ligne.
La règle opérationnelle est simple. N'obligez pas l'infrastructure de lancement à compenser les tests faibles. Utilisez l'infrastructure de lancement 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 responsables de lancement ne traitent plus chaque déploiement comme une mise au jeu. C'est le résultat de faire des tests unitaires React bien.
Si votre équipe délivre React à travers Capacitor ou Electron, la sécurité de lancement dépend de plus que des tests locaux verts. Capgo fournit aux équipes un moyen contrôlé de publier des mises à jour web signées, de cibler les canaux de mise en production et de revenir sur des bundles mauvais sans attendre la revue de la boutique, ce qui s'intègre naturellement derrière un pipeline CI qui exige déjà que les tests unitaires passent avant la mise en production.