Aller au contenu principal
Version : 30.0

Tester des applications React Native

Traduction Bêta Non Officielle

Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →

Chez Facebook, nous utilisons Jest pour tester les applications React Native.

Pour approfondir vos connaissances avec un exemple concret, consultez cette série d'articles : Partie 1 : Jest - Les instantanés entrent en jeu et Partie 2 : Jest - Instantanés Redux pour vos actions et réducteurs.

Configuration

À partir de React Native 0.38, la configuration Jest est incluse par défaut lorsque vous exécutez react-native init. Cette configuration devrait être automatiquement ajoutée à votre fichier package.json :

{
"scripts": {
"test": "jest"
},
"jest": {
"preset": "react-native"
}
}

Exécutez yarn test pour lancer les tests avec Jest.

astuce

Si vous mettez à jour votre application React Native et utilisiez précédemment le preset jest-react-native, supprimez cette dépendance de votre fichier package.json et remplacez le preset par react-native.

Test d'instantané

Créons un test d'instantané pour un petit composant d'introduction contenant quelques vues, composants texte et styles :

Intro.js
import React, {Component} from 'react';
import {StyleSheet, Text, View} from 'react-native';

class Intro extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.instructions}>
This is a React Native snapshot test.
</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor: '#F5FCFF',
flex: 1,
justifyContent: 'center',
},
instructions: {
color: '#333333',
marginBottom: 5,
textAlign: 'center',
},
welcome: {
fontSize: 20,
margin: 10,
textAlign: 'center',
},
});

export default Intro;

Utilisons maintenant le moteur de rendu de test de React et la fonctionnalité d'instantané de Jest pour interagir avec le composant, capturer le rendu et créer un fichier d'instantané :

__tests__/Intro-test.js
import React from 'react';
import renderer from 'react-test-renderer';
import Intro from '../Intro';

test('renders correctly', () => {
const tree = renderer.create(<Intro />).toJSON();
expect(tree).toMatchSnapshot();
});

Lorsque vous exécutez yarn test ou jest, cela générera un fichier de sortie similaire à ceci :

__tests__/__snapshots__/Intro-test.js.snap
exports[`Intro renders correctly 1`] = `
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#F5FCFF",
"flex": 1,
"justifyContent": "center",
}
}>
<Text
style={
Object {
"fontSize": 20,
"margin": 10,
"textAlign": "center",
}
}>
Welcome to React Native!
</Text>
<Text
style={
Object {
"color": "#333333",
"marginBottom": 5,
"textAlign": "center",
}
}>
This is a React Native snapshot test.
</Text>
</View>
`;

Lors des prochains tests, le rendu sera comparé à l'instantané précédent. L'instantané doit être versionné avec les modifications de code. Si un test échoue, vérifiez si le changement est intentionnel ou non. Si le changement est voulu, exécutez jest -u pour écraser l'instantané existant.

Le code de cet exemple est disponible dans examples/react-native.

Configuration du preset

Ce preset configure l'environnement de manière très opinionnée, basée sur nos pratiques chez Facebook. Toutes les options peuvent être surchargées comme avec une configuration manuelle.

Environnement

react-native fournit un preset Jest : le champ jest.preset de votre package.json doit pointer vers react-native. Ce preset utilise un environnement Node qui simule une app React Native. Sans APIs DOM ou navigateur, il améliore significativement le temps de démarrage de Jest.

Personnalisation de transformIgnorePatterns

L'option transformIgnorePatterns spécifie quels fichiers doivent être transformés par Babel. De nombreux modules npm react-native ne pré-compilent malheureusement pas leur code source avant publication.

Par défaut, le preset jest-react-native ne traite que les fichiers sources du projet et react-native. Si vous avez des dépendances npm qui doivent être transformées, vous pouvez personnaliser cette option de configuration en incluant des modules autres que react-native en les regroupant et en les séparant avec l'opérateur | :

{
"transformIgnorePatterns": ["node_modules/(?!((@)?react-native|my-project)/)"]
}

Vous pouvez tester les chemins correspondants (et donc exclus de la transformation) avec un outil comme celui-ci.

transformIgnorePatterns exclut un fichier si son chemin correspond à n'importe quel motif fourni. Diviser en plusieurs motifs peut donc avoir des effets indésirables. Dans l'exemple ci-dessous, les exclusions pour foo et bar s'annulent mutuellement (assertion de négation) :

{
"transformIgnorePatterns": ["node_modules/(?!foo/)", "node_modules/(?!bar/)"] // not what you want
}

setupFiles

Pour ajouter une configuration à chaque fichier de test, utilisez l'option setupFiles pour spécifier des scripts d'initialisation.

moduleNameMapper

L'option moduleNameMapper permet de mapper un chemin de module vers un module différent. Par défaut, le préréglage mappe toutes les images vers un module factice d'image, mais si un module ne peut pas être trouvé, cette option de configuration peut aider :

{
"moduleNameMapper": {
"my-module.js": "<rootDir>/path/to/my-module.js"
}
}

Conseils

Simuler des modules natifs avec jest.mock

Le préréglage Jest intégré à react-native inclut quelques simulations par défaut appliquées à un dépôt React Native. Cependant, certains composants React Native ou tiers dépendent de code natif pour être rendus. Dans ces cas, le système de simulation manuelle de Jest peut aider à simuler l'implémentation sous-jacente.

Par exemple, si votre code dépend d'un composant vidéo natif tiers appelé react-native-video, vous pourriez vouloir le simuler avec une simulation manuelle comme ceci :

jest.mock('react-native-video', () => 'Video');

Cela rendra le composant sous la forme <Video {...props} /> avec toutes ses propriétés dans la sortie du snapshot. Voir aussi les mises en garde concernant Enzyme et React 16.

Parfois, vous devez fournir une simulation manuelle plus complexe. Par exemple, si vous souhaitez transférer les types de propriétés ou les champs statiques d'un composant natif vers une simulation, vous pouvez renvoyer un composant React différent via cet assistant de jest-react-native :

jest.mock('path/to/MyNativeComponent', () => {
const mockComponent = require('react-native/jest/mockComponent');
return mockComponent('path/to/MyNativeComponent');
});

Ou si vous souhaitez créer votre propre mock manuel, vous pouvez faire quelque chose comme ceci :

jest.mock('Text', () => {
const RealComponent = jest.requireActual('Text');
const React = require('react');
class Text extends React.Component {
render() {
return React.createElement('Text', this.props, this.props.children);
}
}
Text.propTypes = RealComponent.propTypes;
return Text;
});

Ou si vous souhaitez créer votre propre simulation manuelle, vous pouvez faire quelque chose comme ceci :

Si vous vous retrouvez à simuler les mêmes modules à plusieurs reprises, il est recommandé de définir ces simulations dans un fichier séparé et de l'ajouter à la liste des setupFiles.