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 fenêtre de demande de permission native, le comportement du clavier, l'animation, la plateforme API ou la pile de navigation réelle.
C'est là où les équipes se font une fausse confiance. Bibliothèque de test React Native est excellent pour tester ce que rend un composant et comment il répond aux interactions utilisateur, mais ce n'est pas un substitut pour les tests sur appareil 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 assertions expliquées
- Modèles pratiques pour les composants, les hooks et la navigation
- Débogage des Tests Fragiles CI et Contrôles de Performance
- Mettre tout cela en place et avancer
Pourquoi le test utilisateur centré change tout
Au commencement, une erreur de test se produit avant même que le test ne soit écrit. Un développeur inspecte les props d'un composant, pénètre dans son état ou compare un grand snapshot car ces détails sont faciles à affirmer. Le test passe, puis une refacteur change la structure du composant sans modifier l'expérience, et le lot se brise. De plus, le test peut continuer à passer alors que le comportement visible 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 Bibliothèque de test React Native centrée sur l'utilisateurUn diagramme illustrant les avantages de la testabilité centrée sur l'utilisateur, mettant en évidence le comportement de l'utilisateur, la résilience, la fiabilité et de meilleures pratiques.

Test the behavior users depend on
Supposez un formulaire de connexion qui désactive son bouton de soumission pendant l'exécution d'une requête. Un test fragile pourrait inspecter disabled 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
Le deuxième test n'a pas d'importance si la forme utilise un état local, un réducteur, un crochet personnalisé ou une mise en œuvre de bouton différent. Il s'assure que l'application transmet le résultat correct.
Règle pratique : Si un utilisateur ne peut pas l'observer, il faut se demander s'il s'agit d'un comportement à tester dans une composante.
Les requêtes basées sur les étiquettes d'accèsibilité et les rôles forcent également un produit code de meilleure qualité. Une écran 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. l'expérience utilisateur de l'application, car la testabilité et l'utilisabilité s'améliorent souvent ensemble.
Savoir que les tests réussis ne prouvent rien
Un test de composant centré sur l'utilisateur peut prouver que JavaScript rend la branchement attendu et répond à une pression simulée. Il ne peut pas prouver que la demande de prompt biométrique s'ouvre correctement, que la caméra native retourne un résultat utilisable ou que la flux de paiement survit au comportement de cycle de vie spécifique de 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 de composant, 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 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
La plus ancienne react-native-testing-library Le nom de package npm existe toujours comme artefact historique, mais les projets actuels doivent utiliser le package scoping maintenu au sein de la famille de Testing Library. Le projet’s le dépôt GitHub le décrit comme outils React Native pour encourager de bonnes pratiques de test, et son historique de publication montre que la bibliothèque a continué à changer aux côtés de React Native plutôt que de rester un assistant statique.
Installez la bibliothèque avec votre environnement Jest existant. Les projets Expo utilisent couramment le preset Jest Expo, tandis que les projets React Native bare peuvent utiliser le preset React Native :
npm install --save-dev @testing-library/react-native jest
Pour Expo, ajoutez le preset que votre projet utilise déjà :
{
"scripts": {
"test": "jest"
},
"jest": {
"preset": "jest-expo"
}
}
Pour une application React Native bare, utilisez la configuration Jest correspondante au lieu de React Native. Gardez le preset aligné avec la version du framework. Beaucoup d'erreurs qui semblent être des problèmes RNTL proviennent d'une mise à l'échelle 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';
Ensuite, référez-vous à 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 a besoin de la même attention. Assurez-vous que Jest transforme .ts et (Et) .tsx les fichiers à travers le jeu de configuration ou votre configuration Babel, et maintenez les types de test disponibles au compilateur. Un test qui s'exécute 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.
La chronologie des versions est utile pour diagnostiquer des conseils de configuration plus anciens. Les listes de projets. 127 versions, avec v14.0.1 étiqueté le 23 juin 2026, tandis que v12.9.0, publié le 27 novembre 2024, ajoute un support officiel pour React Native 0.77 et Expo 52. La ligne alpha v14 en mars 2025 a migré vers le rendu de test universel à partir du rendu de test React obsolète et s'est préparé pour le support React 19 uniquement. Ces détails apparaissent dans l' historique des versions RNTL, donc n'importez pas 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 JestAlors, exécutez un test de composant petit avant d'ajouter la navigation et les mocks natifs.

APIs, requêtes et affirmations centrales 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 les détails de l'implémentation peut rendre un test réussi trompeur.
Commencez par render:
const screen = render(<LoginForm />);
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 sélectionneur pertinent pour l'utilisateur ou où une prise en charge intégrée stable est nécessaire.

Pick the query by timing and intent
Chaque famille de requêtes a un but distinct :
- Présence synchrone : Utilisez
getByRole,getByText, ou un autregetByLa recherche de l'élément doit déjà exister. Le test échoue immédiatement si ce n'est pas le cas. - Apparition asynchrone : Utilisez
findByRoleoufindByTextwhen rendering or interaction causes an async update. - Contrôles d'absence: Utilisez
queryByTextouqueryByTestIdLorsqu'un élément peut manquer et qu'un résultat null est attendu au lieu d'une exception. - Sélecteurs de fallback : Utilisez
getByTestIdsciemment. Cela donne un crochet durable aux contrôles complexes, mais ne doit pas remplacer les étiquettes accessibles à travers l'application.
Pour les tests d'événements ciblés, fireEvent.press est direct :
fireEvent.press(screen.getByRole('button', { name: 'Save' }));
Utiliser userEvent lorsque la version installée prend en charge la séquence d'interaction plus réaliste. Dans les deux cas, affirmez l'interface utilisateur résultante :
expect(await screen.findByText('Saved')).toBeTruthy();
Une assertion de gestionnaire convient à un composant dont le contrat public est un appel de callback d'événement. C'est faible comme preuve unique que le parcours utilisateur fonctionne.
Préférez les assertions spécifiques aux captures d'écran
Les bonnes assertions 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ès, la sélection et les retours d'informations de validation visibles. Évitez de vérifier les connexions internes.
expect(screen.getByTestId('submit-button').props.onPress).toBeDefined();
Cette assertion prouve que la propriété existe, et non que la fonctionnalité fonctionne. Les captures d'écran intentionnelles et petites peuvent capturer les changements structurels, tandis que les captures d'écran de navigation ou d'écran larges créent souvent des commentaires bruyants et rendent les mises à jour non expliquées faciles à approuver.
La bibliothèque de test appartient à un écosystème plus large testing-library npm organisation. Ses packages actifs incluent @testing-library/react-nativeavec version 13.3.3 publié en 2026selon les informations du projet d'après les informations du dépôtConventions de requêtes partagées sont utiles sur plusieurs plateformes, mais elles ne déterminent pas quelle assertion représente votre comportement produit.
Voir ce guide pour une comparaison plus large des pratiques de test de composants avec Jest. testage unitaire React. RNTL still stops at the JavaScript-rendered component boundary. Native permissions, real navigation stacks, device keyboards, frame timing, and memory behavior need E2E or performance tooling rather than more component mocks.
Modèles pratiques pour les composants, les hooks et la navigation
Modèles pratiques pour les composants, les hooks et la navigation
A useful test suite follows the shape of the application. Presentational components need direct behavior tests, hooks need controlled inputs and outputs, navigation needs a realistic enough provider, and native modules need mocks that remain visibly different from real-device verification.

Composants présentatifs
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'implémentez pas par défaut la moitié de tous les composants enfants. Implémentez uniquement les limites coûteuses ou non liées lorsque celles-ci obscurcissent le comportement à tester.
Pour une fonctionnalité personnalisée, utilisez renderHook Lorsque la version d'installation de RNTL la fournit :
const { result } = renderHook(() => useSearch());
await act(async () => {
await result.current.submit('query');
});
expect(result.current.status).toBe('success');
Le test de la fonctionnalité doit contrôler la limite réseau ou de répertoire, et non reproduire l'ensemble de l'application. Testez l'écran séparément afin de savoir si l'état de la fonctionnalité devient utile pour l'interface.
Navigation et données asynchrones
Pour le comportement de navigation, afficher une écran à l'intérieur d'un NavigationContainer and a small test navigator is often more valuable than mocking every navigation method. Press a visible control, wait for the destination content, and assert the new screen’s output. A direct useNavigation Les données asynchrones méritent le même discernement. Simulez la réponse du __CAPGO_KEEP_0__ ou du répertoire, générez l'écran, affirmez l'état de chargement, résolvez la demande, puis affirmez le résultat de succès ou d'erreur. Utilisez
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 Vérifiez que les requêtes attendues se produisent effectivement et faites explicitement les requêtes rejetées, sinon une test peut passer car le composant n'a jamais atteint la branch ciblée.
Modules natifs simulés
Les simulations pour AsyncStorage, les permissions, les appareils photo, les biométriques et les API de plateforme sont utiles pour les tests JavaScript déterministes. Elles ne constituent pas la preuve que la fonctionnalité native fonctionne. Gardez le comportement de simulation proche du contrat de module, réinitialisez les appels entre les tests et incluez les réponses d'erreur au lieu de modéliser uniquement le chemin heureux.
| Scénario | Meilleur avec RNTL | Besoin de validation E2E |
|---|---|---|
| La validation de formulaire et les erreurs visibles | Oui | Ordinairement pas |
| Loading, success, and error UI from a mocked repository | Oui | Pour flux de production critique |
| Pour un flux de production critique | Oui, avec un navigateur de test | Oui lorsque les gestes, les liens profonds ou le comportement de la plateforme comptent |
| Les décisions d'état d'AsyncStorage | Oui, avec un mock contrôlé | Oui, lorsqu'interagissent lancement et persistance avec le cycle de vie natif. |
| Capteurs, biométriques, autorisations, ou API de plateforme | Fallback JavaScript et logique de branching | Oui, sur des appareils réels ou représentatifs |
| La disposition, les performances de rendu et le code natif | 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.
Diagnostic des Tests Fragiles CI et Contrôles de Performance
Un test fragile indique souvent un temps non contrôlé, un état partagé ou une assertion qui concurrence l'interface utilisateur. Identifiez la condition présente avant d'augmenter les temps d'attente. Un temps d'attente plus long peut cacher le problème de planification et rendre l'ensemble 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. Un act Avertissement signifie que React a observé une mise à jour en dehors de son espace d'interaction attendu. Corrigez la mise à jour manquante. awaitSupprimez plutôt la suppression de la mise à jour.
Faites les échecs CI reproductibles
Les échecs CI nécessaires doivent faire l'objet d'une comparaison de l'environnement avant une refonte du composant. Vérifiez Node, le gestionnaire de package, les paramètres de travail de Jest, la configuration des temporisateurs et les variables d'environnement. Reproduisez la même commande localement si possible, puis réduisez le test échouant à l'interaction la plus petite qui expose la différence.
CI-only failures need an environment comparison before a component rewrite. Check Node, the package manager, Jest worker settings, timer configuration, and environment variables. Reproduce the same command locally where possible, then reduce the failing test to the smallest interaction that exposes the difference.
Observabilité couvre un autre fossé. Un outil comme Sentry pour React Native fournit le contexte d'erreur de production qui ne peut être reproduit par les tests de composants mockés, 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 au niveau de l'appareil pour le transfert et le comportement natif. Pour les flux uniques-code, consultez les lignes directrices sur la manière de tester les flux de vérification par SMS lorsque cette intégration fait partie du parcours.
Traitez la performance comme une mesure, pas une affirmation.
Un test fonctionnel peut confirmer que la liste s'affiche. Il ne peut pas déterminer de manière fiable si une refacteur a changé la durée de rendu ou le nombre de rendus, car le temps de lancement du test ajoute du bruit. Rassurez-vous en mesurant ces valeurs pour un scénario, en répétant le scénario pour réduire la variance, et en appliquant une analyse statistique avant de signaler une modification significative. Son documentation de test de performances couvre également la présentation adaptée aux CI et aux examens de demande de tirage.
Évitez les affirmations 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 appartient à la couche large et rapide de votre stratégie de test. Elle doit couvrir le comportement des composants, les changements d'état visibles, les résultats d'accèsibilité, la validation, les états de données simulés et l'intégration entre les composants JavaScript. Gardez ces tests axés sur ce que l'utilisateur peut observer, et faites en sorte que les échecs pointent vers un comportement spécifique plutôt qu'une grande arborescence affichée.
La couche plus petite basée sur les appareils doit protéger les flux où les mocks peuvent se trouver. La Résumé des tests indique que RNTL ne fournit pas un runtime React Native complet et ne peut donc pas 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.
- Conservation des tests commerciaux précieux. Déplacez l'état pur et la logique de domaine dans des tests unitaires ciblés qui fournissent un feedback clair.
- Remplacez les assertions d'implémentation en premier lieu. Vérifiez les vérifications de propriété et d'état interne en tant que sortie visible, état d'accessibilité et résultats d'interaction.
- Réduisez les captures d'écran. Conservation que les captures d'écran que les réviseurs peuvent comprendre et maintenir.
- Ajoutez une couverture de bordure native. Pour chaque module important mocké, identifiez le comportement du dispositif qui nécessite encore une validation.
- Protégez les parcours critiques. Ajoutez une couverture E2E pour l'authentification, les paiements, la navigation de base, les permissions et d'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 et les chemins de rendu coûteux au lieu de deviner d'après la durée de Jest.
Pour une confiance de version, connectez le suite à 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 rollback. 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 relie 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 rollback. Visitez Capgo pour voir comment cela peut s'intégrer à votre composant, les tests E2E et CI.