Votre suite de tests React Native est verte, mais un utilisateur signale toujours que le bouton « Continuer » ne fait rien sur un appareil réel. Le test du composant a trouvé le bouton, a appelé son gestionnaire et a vu l'écran attendu dans un environnement JavaScript mocké. Il n'a jamais vérifié la demande de permission native, le comportement de la touche, l'animation, la plateforme API ou la pile de navigation réelle.
C'est là que les équipes se font une confiance fausse. React Native Testing Library est excellent pour tester ce que rend un composant et comment il répond aux interactions de l'utilisateur, mais ce n'est pas un substitut aux tests de dispositif ou à la mesure de performance. La stratégie fiable est d'utiliser chaque couche pour les échecs qu'elle peut révéler.
Table des Matières
- Pourquoi le Test Utilisateur Centré Change Tout
- Installation et Configuration Qui Fonctionnent Vraiment
- APIs de Base, Requêtes et Affirmations Expliquées
- Modèles Pratiques pour les Composants, les Hooks et la Navigation
- Débogage des tests flous, contrôles CI et performances
- Réunir tout et avancer
Pourquoi le test utilisateur centré change tout
Un échec de test commun commence avant même que le test soit écrit. Un développeur inspecte les props d'un composant, y accède à son état, ou compare un grand snapshot car ces détails sont faciles à affirmer. Le test passe, puis une refonte change la structure du composant sans changer l'expérience, et le lot se brise. De plus, le test peut continuer à passer alors que le comportement visible pour l'utilisateur est incorrect car l'affirmation n'a jamais décrit ce que l'utilisateur doit voir.
La bibliothèque de test React Native prend l'approche inverse. Vous affichez le composant, interagissez avec lui à travers un contrôle visible, puis affirmez le résultat que l'utilisateur peut observer. Cette approche correspond à l'exemple utilisateur centré de la bibliothèque de test React NativeComme bien le React Native, la documentation de test pour conserver les tests courts, se concentrer sur chaque test sur une chose, séparer les préoccupations de vue des logiques métier et d'état, et préférer les sorties visibles ou les aides d'accès aux détails d'implémentation internes.

Testez le comportement dont les utilisateurs dépendent.
Supposons un formulaire de connexion qui désactive son bouton de soumission pendant une requête s'exécute. Un test fragile pourrait inspecter disabled sur une instance de composant particulière ou affirmer que la variable d'état a changé. Un test plus fort appuie le contrôle « S'inscrire » accessible, attend que l'indicateur de chargement apparaisse et vérifie que le message d'erreur ou l'écran de destination apparaît.
Le deuxième test ne s'intéresse pas à savoir si le formulaire utilise un état local, un réducteur, une fonction personnalisée ou une mise en œuvre de bouton différent. Il s'intéresse à ce que l'application communique le résultat correct.
Règle pratique: Si un utilisateur ne peut pas l'observer, questionnez-vous si cela appartient à un test de comportement de composant.
Les requêtes basées sur les étiquettes d'accèsibilité et les rôles forcent également de meilleures pratiques de produit code. Une page qui expose des étiquettes significatives est plus facile à utiliser avec des technologies d'assistance et plus facile à exercer en tests. Cette connexion compte lorsqu'on évalue l'expérience utilisateur plus large. parce que la testabilité et l'usabilité s'améliorent souvent ensemble.Sachez ce que les tests qui passent ne prouvent pas.
Know what passing tests don’t prove
A un test de composant centré sur l'utilisateur, il est possible de prouver que JavaScript affiche la branch attendue et répond à un pressage simulé. Il ne peut pas prouver que la prompte biométrique s'ouvre correctement, que la caméra native retourne un résultat utilisable ou que le flux de paiement survit au comportement de cycle de vie spécifique à la plateforme.
Cette limite n'est pas une faiblesse de la bibliothèque. C'est une raison de garder les couches de test honnêtes. Utilisez RNTL pour le comportement des composants, puis réservez les tests basés sur le dispositif pour les flux où l'intégration native, la navigation réelle, les permissions, l'authentification, les paiements ou la fonctionnalité de l'application de base peuvent changer le résultat.
Installation et Configuration Qui Fonctionnent Vraiment
La mise en place moderne commence par le package scoping :
@testing-library/react-native
Le package de nom de domaine plus ancien existe encore comme artefact historique, mais les projets actuels doivent utiliser le package scoping maintenu au sein de la famille de la Bibliothèque de Test. Le dépôt du projet react-native-testing-library npm GitHub repository Installez la bibliothèque avec votre environnement Jest existant. Les projets Expo utilisent couramment le preset Jest d'Expo, tandis que les projets React Native sans enveloppe peuvent utiliser le preset React Native :
Pour Expo, ajoutez le preset que votre projet utilise déjà :
npm install --save-dev @testing-library/react-native jest
__CAPGO_KEEP_0__
{
"scripts": {
"test": "jest"
},
"jest": {
"preset": "jest-expo"
}
}
Pour une application React Native nue, utilisez la configuration Jest correspondante de React Native à la place. Gardez le preset aligné avec la version du framework. Beaucoup d'erreurs qui ressemblent à des problèmes RNTL proviennent d'une mise à jour React renderer, d'une transformation Babel ou d'un preset Jest incohérent.
Conservez les fichiers de configuration explicites
Placez la configuration de l'environnement partagé dans un fichier de configuration plutôt que de répéter les mocks dans chaque test :
// jest.setup.js
import '@testing-library/react-native/extend-expect';
Référez-y ensuite à partir de Jest :
{
"jest": {
"preset": "jest-expo",
"setupFilesAfterEnv": ["<rootDir>/jest.setup.js"]
}
}
Si votre application utilise React Navigation, Reanimated, la gestion de gestes, le contexte de zone de sécurité ou les modules de stockage, configurez uniquement les mocks dont votre environnement de test a besoin. Un mock global qui change le comportement de l'application peut rendre chaque test plus facile à passer, mais rend la suite moins fiable.
TypeScript nécessite la même attention. Assurez-vous que Jest transforme .ts et .tsx context : Page/zone : Site de marketing Capgo. Rôle : Étiquette de navigation ou élément UI court. Vu dans : page trust.astro. Clé de message `et` (Et).
les fichiers de test à travers le preset ou votre configuration Babel, et conservez les types de test disponibles pour le compilateur. Un test qui fonctionne localement mais n'est pas vérifié par type peut cacher des noms de requêtes incorrects, des paramètres de navigation invalides ou des formes de mock non sûres. L'historique des versions est utile pour diagnostiquer des conseils de configuration plus anciens. Le projet liste127 versions , avec : « version 14.0.1 taguée le 23 juin 2026 »v12.9.0, publié le 2024-11-27, a ajouté un support officiel pour React Native 0.77 et Expo 52. . La ligne alpha v14 en mars 2025 a migré vers le Renderiseur de tests universel à partir du Renderiseur de tests React obsolète et s'est préparé pour un support React 19 uniquement.ces détails apparaissent dans l' historique de la version de RNTL, il ne faut donc pas copier une dépendance de rendu d'un tutoriel obsolète sans vérifier les versions de votre application.
Pour une fondation Jest pratique, comparez votre configuration avec ce guide de test unitaire de Jest, puis exécutez un petit test de composant avant d'ajouter la navigation et les mocks natifs.

APIs de base, requêtes et assertions expliquées.
Les tests RNTL deviennent fiables lorsque leurs requêtes correspondent à ce que les utilisateurs peuvent voir, trouver et utiliser. L’API est petit, mais choisir un sélecteur qui expose des détails d'implémentation peut rendre un test réussi trompeur.
Commencez par render:
const screen = render(<LoginForm />);
Choisissez la requête la plus pertinente pour l'utilisateur. Préférez les requêtes orientées accessibilité lorsque le composant les expose, utilisez le texte visible lorsque le texte est le comportement, et réservez testID pour les cas sans un sélecteur pertinent pour l'utilisateur ou où une prise en charge intégrée stable est nécessaire.

Choisissez la requête en fonction du temps et de l'intention
Chaque famille de requêtes a un but distinct :
- Présence synchronise : Utilisez
getByRole,getByTextou une autregetByrequête lorsque l'élément doit déjà exister. Le test échoue immédiatement si ce n'est pas le cas. - Apparition asynchrone : Utilisez
findByRoleoufindByTextWhen l'interaction ou la mise à jour asynchrone provoque une mise à jour. - Vérifications d'absence : Utilisez
queryByTextouqueryByTestIdQuand une mise à jour asynchrone est provoquée par l'interaction ou la mise à jour. - Vérifications d'absence : Utilisez
getByTestIdQuand une mise à jour asynchrone est provoquée par l'interaction ou la mise à jour.
Quand une mise à jour asynchrone est provoquée par l'interaction ou la mise à jour. fireEvent.press Vérifications d'absence :
fireEvent.press(screen.getByRole('button', { name: 'Save' }));
Utilisez userEvent Quand un élément peut manquer et qu'un résultat null est attendu au lieu d'une exception.
expect(await screen.findByText('Saved')).toBeTruthy();
Affirmation de gestion d'un handler convient à un composant dont le contrat public est un appel de callback. Elle est faible car c'est la seule preuve que le parcours utilisateur fonctionne.
Préférez les affirmations spécifiques aux captures d'écran.
Les bonnes affirmations décrivent l'écran :
expect(screen.getByText('Account created')).toBeTruthy();
expect(screen.getByRole('button', { name: 'Continue' })).toBeEnabled();
Ils peuvent également vérifier l'état d'accèsibilité, la sélection et les retours d'informations de validation visibles. Évitez de vérifier la mise en œuvre interne :
expect(screen.getByTestId('submit-button').props.onPress).toBeDefined();
Cette affirmation prouve que la propriété existe, et non que la fonctionnalité fonctionne. Les captures d'écran intentionnelles et petites peuvent détecter les changements structurels, tandis que les captures d'écran de navigation ou d'écran importantes créent souvent des commentaires bruyants et rendent les mises à jour non expliquées faciles à approuver.
Le package de la bibliothèque de test appartient à l'organisation plus large testing-library npm . Ses packages actifs incluent @testing-library/react-native avec la version 13.3.3 publié en 2026 selon les informations du dépôt du projet . Les conventions de requêtes partagées aident sur plusieurs plateformes, mais elles ne décident pas quelle affirmation représente le comportement de votre produit.13.3.3 publié en 2026
Pour une comparaison plus large des pratiques de test de composants Jest, consultez ce guide à le test unitaire de React. RNTL s'arrête toujours à la limite du composant JavaScript rendu. Les permissions natives, les piles de navigation réelles, les claviers de dispositif, les temps de cadre et le comportement de la mémoire nécessitent des outils de test E2E ou de performance plutôt que des mocks de composants supplémentaires.
Le vidéo ci-dessous démontre le flux de requête et d'affirmation dans le contexte.
Des modèles pratiques pour les composants, les hooks et la navigation
Un ensemble de tests utiles suit la forme de l'application. Les composants présentationnels nécessitent des tests de comportement directs, les hooks nécessitent des entrées et des sorties contrôlées, la navigation nécessite un fournisseur réaliste suffisamment réaliste et les modules natifs nécessitent des mocks qui restent visiblement différents de la vérification de la réalité sur un appareil mobile.

Les composants présentationnels
Conservez un test de composant proche de son contrat public :
const onSelect = jest.fn();
render(
<PlanCard
title="Team"
description="Shared workspace"
onSelect={onSelect}
/>
);
fireEvent.press(screen.getByRole('button', { name: 'Choose Team' }));
expect(onSelect).toHaveBeenCalled();
Le label exact doit correspondre à votre interface. La partie importante est que le test trouve le contrôle de la même manière qu'un utilisateur ou un service d'accessibilité et confirme le résultat visible ou de rappel qui compte. N'écrivez pas par défaut un mock pour chaque composant enfant. Mockez les limites coûteuses ou non liées uniquement lorsque cela obscurcit le comportement à tester.
Pour un hook personnalisé, utilisez renderHook lorsque la version installée de RNTL le fournit :
const { result } = renderHook(() => useSearch());
await act(async () => {
await result.current.submit('query');
});
expect(result.current.status).toBe('success');
La fonctionnalité de test doit contrôler la limite réseau ou de répertoire, et non reproduire l'application entière. Testez l'écran séparément afin de savoir si l'état de la fonctionnalité devient utile pour l'interface utilisateur.
Navigation et données asynchrones
Pour le comportement de navigation, afficher une écran à l'intérieur d'un navigateur réel NavigationContainer et un petit navigateur de test est souvent plus précieux que de simuler tous les méthodes de navigation. Appuyez sur un contrôle visible, attendez le contenu de destination, et affirmez la sortie de l'écran nouveau. Un mock direct est toujours approprié pour un petit bouton dont la seule responsabilité est de dispatcher une route typée, mais il ne validera pas l'enregistrement de la route, les paramètres ou le comportement du navigateur imbriqué. useNavigation Déserves les mêmes règles. Simulez la réponse du __CAPGO_KEEP_0__ ou du répertoire, affichez l'écran, affirmez l'état de chargement, résolvez la demande, puis affirmez la sortie de succès ou d'erreur. Utilisez les requêtes pour les éléments attendus ultérieurs et faites les requêtes refusées explicites, sinon un test peut passer parce que le composant n'a jamais atteint la branche prévue.
Async data deserves the same discipline. Mock the API or repository response, render the screen, assert the loading state, resolve the request, then assert success or error output. Use findBy Mocks pour AsyncStorage, les permissions, les appareils photo, les biométries et les API de plateforme sont utiles pour les tests JavaScript déterministes. Ils ne sont pas la preuve que la fonctionnalité native fonctionne. Gardez le comportement de mock proche du contrat du module, réinitialisez les appels entre les tests, et incluez les réponses de failure au lieu de modéliser uniquement la voie heureuse.
Scénario
Meilleur avec RNTL
| Besoin de validation E2E | Best With RNTL | Needs E2E Validation |
|---|---|---|
| Validation de formulaire et d'erreurs visibles | Oui | Non, généralement |
| Chargement, succès et erreurs d'interface utilisateur à partir d'un référentiel simulé | Oui | Pour un flux de production critique |
| Navigation entre les écrans enregistrés | Oui, avec un navigateur de test | Oui lorsque les gestes, les liens profonds ou le comportement du système d'exploitation sont importants |
| Décisions sur l'état de l'AsyncStorage | Oui, avec un mock contrôlé | Oui lorsque le lancement et la persistance interagissent avec le cycle de vie natif |
| Caméras, biométriques, autorisations, ou API de plateforme | Logique de fallback JS et de branchement | Oui, sur des appareils réels ou représentatifs |
| Disposition, performance de rendu et native code | Non | Oui, avec un appareil ou un outil spécialisé |
La limite est pratique : simulez la dépendance pour tester vos décisions JavaScript, puis exécutez un test d'appareil pour confirmer le comportement réel de la dépendance.
Débogage des Tests Fluctuants, Contrôles de Performance et CI
Un test fluctuant indique souvent un temps non contrôlé, un état partagé ou une assertion qui courtise l'interface utilisateur. Identifiez quelle condition est présente avant d'augmenter les temps limites. Un temps limite plus long peut cacher le problème de planification et rendre le lot plus lent.
Utilisez findBy pour les éléments attendus après une mise à jour. Utilisez waitFor pour les conditions d'état ou les appels de mock. Si les temporisateurs faux sont activés, avancez-les au point où l'interaction nécessite et restaurez les temporisateurs réels par la suite. act Le message d'avertissement signifie que React a observé une mise à jour en dehors de son espace d'interaction attendu. Corrigez la mise à jour manquante, l'interaction utilisateur ou la mise à jour du chronomètre au lieu de supprimer l'avertissement. awaitFixez les échecs de CI
Un job CI fiable installe à partir du fichier de verrouillage, exécute la même commande Jest utilisée localement et isole l'état de mock. Effacez les appels de mock entre les tests, réinitialisez les modules lorsque l'état de module affecte le comportement et supprimez les dépendances de l'ordre d'exécution. La mise en cache de Jest accélère les retours, mais les changements de dépendances ou de configuration nécessitent une invalidation de cache appropriée.
Les échecs CI nécessaires d'un environnement nécessitent une comparaison de l'environnement avant une refonte du composant. Vérifiez Node, le gestionnaire de packages, les paramètres de travail de Jest, la configuration du chronomètre et les variables d'environnement. Répétez la même commande localement dans la mesure du possible, puis réduisez le test en échec à l'interaction la plus petite qui expose la différence.
L'observabilité couvre un autre fossé. Un outil tel que
Sentry pour React Native fournit le contexte d'erreur de production que les tests de composants mockés ne peuvent pas reproduire, y compris les échecs liés aux appareils réels et aux intégrations natives. Les parcours sensibles à la sécurité nécessitent une deuxième limite. Utilisez les tests de composants pour la validation et les transitions d'état, puis ajoutez une couverture à niveau d'appareil pour le transfert et le comportement natif. Pour les flux uniques-__CAPGO_KEEP_0__, consultez les conseils sur la façon de
Security-sensitive journeys need a second boundary. Use component tests for validation and state transitions, then add device-level coverage for the handoff and native behavior. For one-time-code flows, consult guidance on how to lorsqu'intégration forme partie du parcours. Traitez les performances comme des mesures, et non des affirmations.
Treat performance as measurement, not assertion
Un test fonctionnel peut confirmer que la liste s'affiche. Il ne peut pas déterminer de manière fiable si une refonte a changé la durée de rendu ou le nombre de rendus, car le temps de lancement du test ajoute du bruit. Les mesures réassurent ces valeurs pour un scénario, répètent le scénario pour réduire la variance et appliquent une analyse statistique avant de signaler une modification significative. la documentation de test de performance la documentation de test de performance couvre également les rapports appropriés pour les CI et les examens de demande de tirage.
Évitez les assertions fixes telles que « ce rendu doit se terminer en dessous d'un seuil choisi. » Un travailleur CI occupé peut déclencher une fausse erreur, tandis qu'un seuil lâche peut manquer une régression réelle. Utilisez des mesures répétées pour les signaux de régression, puis inspectez le composant et le profil de l'appareil lorsque la comparaison montre une différence significative.
Règle de mesure : Les tests fonctionnels répondent à la question de savoir si le comportement est correct. Les outils de performance répondent à la question de savoir si un scénario mesuré a changé. Gardez ces questions séparées.
Mettre tout en place et avancer
La bibliothèque de test React Native doit se trouver dans la couche rapide et large de votre stratégie de test. Elle doit couvrir le comportement des composants, les changements d'état visibles, les résultats d'accès, la validation, les états de données mockés et l'intégration entre les composants JavaScript. Gardez ces tests focalisés sur ce que l'utilisateur peut observer, et faites en sorte que les erreurs pointent vers un comportement spécifique plutôt qu'un grand arbre rendu.
La couche plus petite basée sur les appareils doit protéger les flux où les mocks peuvent se trouver. La vue d'ensemble de test de React Native La couche plus petite basée sur les appareils doit protéger les flux où les mocks peuvent se trouver. La vue d'ensemble de test de React Native affirme que RNTL ne fournit pas un runtime React Native complet et ne permet pas de tester les fonctionnalités natives. La même orientation recommande de pairer les tests de composants avec des outils E2E tels que Detox pour les flux critiques, notamment l'authentification, les paiements et la fonctionnalité de base de l'application.
Un chemin de migration pratique
Vous n'avez pas besoin de réécrire un ensemble existant en une seule passe.
- Conservez les tests commerciaux précieux. Déplacez la logique de l'état et du domaine dans des tests unitaires ciblés où ils fournissent un feedback clair.
- Remplacez les assertions d'implémentation en premier. Changez les vérifications des propriétés et de l'état interne en sortie visible, dans l'état d'accessibilité et dans les résultats d'interaction.
- Réduisez les captures d'écran. Conservez uniquement les captures d'écran que les réviseurs peuvent comprendre et maintenir.
- Ajoutez une couverture des limites natives. Pour chaque module mocké important, identifiez le comportement du périphérique qui nécessite encore une validation.
- Protégez les parcours critiques. Ajoutez une couverture E2E pour l'authentification, le paiement, la navigation de base, les permissions et les autres flux où le comportement natif peut modifier le résultat.
- Mesurez les écrans sensibles séparément. Utilisez des comparaisons de performances répétées pour les listes, les flux de données et les chemins de rendu coûteux au lieu de deviner à partir de la durée de Jest.
Pour la confiance de la mise en production, connectez le jeu de tests à l'intégration de CI/CD et exigez le niveau de test approprié avant de livrer. Si une correction JavaScript ou d'actif doit atteindre les utilisateurs après validation, Capgo peut livrer des bundles web signés vers les canaux ciblés pour les applications CapacitorJS et Electron, avec des contrôles de lancement et une protection de retrait. Ce flux de livraison ne remplace pas les tests de dispositifs React Native, mais il illustre le même principe : validez le comportement au niveau où il s'exécute.
La bonne question n'est pas de savoir si la bibliothèque de tests React Native peut tester votre application entière. Elle ne le peut pas, et la limite officielle est utile. La bonne question est de savoir si chaque risque important a un test exécuté dans l'environnement capable de l'exposer.
Capgo connecte les modifications JavaScript et d'actifs validées à une livraison contrôlée pour les équipes CapacitorJS et Electron, avec des canaux ciblés, une visibilité de lancement et une protection de retrait. Visitez Capgo context