Testing React Native Apps
At Facebook, we use Jest to test React Native applications.
Dobândiți o înţelegere mai profundă în testarea unei aplicații exemplu React Native citind următoarele serii: Partea 1: Jest – Instantaneele intră în joc şi Partea 2: Jest – Instantanee Redux pentru Acţiuni şi Reductori.
Instalare
Incepand cu versiunea react-native 0.38, instalarea Jest este inclusă implicit atunci când se rulează react-native init
. Urmatoarea configuratie ar trebui să fie adăugată automat în fişierul package.json:
{
"scripts": {
"test": "jest"
},
"jest": {
"preset": "react-native"
}
}
Notă: Dacă actualizați aplicaţia react-native şi ați utilizat anterior presetarea jest-react-native
, elimina dependenţa din fişierul package.json
şi schimbați presetarea cu react-native
.
Run yarn test
to run tests with Jest.
Testarea de imagine
Să creăm un test de imagine pentru o componentă micuță cu câteva view-uri şi componente de text şi unele stiluri:
// 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;
Acum haideţi să utilizăm procesorul de randare React şi funcționalitatea din Jest pentru testarea de imagine pentru a interacţiona cu componenta şi a captura rezultatul şi a crea un fişier de imagine:
// __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();
});
When you run yarn test
or jest
, this will produce an output file like this:
// __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>
`;
Data viitoare când executaţi testele, rezultatul va fi comparat cu imaginea creată anterior. The snapshot should be committed along with code changes. Atunci când un test de imagine eșuează, trebuie să inspectați dacă este vorba de o modificare intenționată sau neintenţionată. În cazul în care schimbarea este intenționată se poate apela Jest cu jest -u
pentru a suprascrie imaginea existentă.
The code for this example is available at examples/react-native.
Configurarea presetării
Presetarea inițializează mediul şi este foarte dogmatic și se bazează pe ceea ce am găsit a fi util la Facebook. Toate opţiunile de configurare pot fi suprascrise aşa cum acestea pot fi personalizate atunci când nu se utilizează nicio presetare.
Mediu
react-native
este livrat cu o presetare Jest, astfel încât câmpul jest.preset
din package.json
ar trebui să indice către react-native
. Presetul este un mediu de node, care imită mediul unei aplicaţii React Native. Deoarece acesta nu incarca niciun API din DOM sau din browser, aceasta îmbunătăţeşte substanțial timpul de pornire Jest.
Personalizări de transformIgnorePatterns
The transformIgnorePatterns
option can be used to specify which files shall be transformed by Babel. Din păcate multe module npm pentru react-native nu au codul sursă pre-compilat înainte de publicare.
Implicit presetul jest-react-native doar procesează fişierele sursă din proiect şi react-native. If you have npm dependencies that have to be transformed you can customize this configuration option by including modules other than react-native:
{
"transformIgnorePatterns": [
"node_modules/(?!(react-native|my-project|react-native-button)/)"
]
}
setupFiles
Dacă doriţi să specificați configurări suplimentare pentru fiecare fişier de test, opţiunea de configurare setupFiles
poate fi folosită pentru a specifica script-uri de inițializare.
moduleNameMapper
Opțiunea moduleNameMapper
poate fi utilizată pentru maparea o cale de modul către un modul diferit. În mod implicit presetarea mapează toate imaginile către un modul dublură de imagine dar dacă un modul nu poate fi găsit această opţiune de configurare poate ajuta:
{
"moduleNameMapper": {
"my-module.js": "<rootDir>/path/to/my-module.js"
}
}
Recomandări
Mock-uiți module native cu jest.mock
Presetarea Jest incorporată în react-native
vine cu câteva mock-uri implicite, care sunt aplicate pe un proiect react-native. However, some react-native components or third party components rely on native code to be rendered. În astfel de cazuri, sistem manual de mocking din Jest poate ajuta pentru dublarea implementării.
De exemplu, în cazul în care codul vostru depinde de o componentă video nativă externă numită react-native-video
aţi putea-o dubla cu un mock manual în felul următor:
jest.mock('react-native-video', () => 'Video');
Acest lucru va randa componenta ca <Video {...props} />
cu toate proprietățile sale regăsite în instantaneu. See also caveats around Enzyme and React 16.
Uneori, este nevoie să furnizați o dublură manuală mai complexă. De exemplu în cazul în care doriţi să redirecţionaţi proprietăți sau câmpuri statice ale unei componente native către mock, puteţi returna o componentă React diferită dintr-un mock prin acest ajutor din jest-react-native:
jest.mock('path/to/MyNativeComponent', () => {
const mockComponent = require('react-native/jest/mockComponent');
return mockComponent('path/to/MyNativeComponent');
});
Sau dacă doriţi să vă creați propriul mock manual, puteţi face ceva de genul acesta:
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;
});
În alte cazuri, poate doriţi să mock-uiți un modul nativ, care nu este o componentă React. Aceeași tehnică poate fi aplicată. Se recomandă inspectarea codului sursă din modulul nativ şi logarea atunci când rulează o aplicaţie react native pe un dispozitiv real şi apoi modelarea unui mock manual după modulul real.
Dacă ajungeți să mock-uiți aceleași module de multe ori este recomandată definirea acestor mock-uri într-un fişier separat şi adăugarea lor la lista de setupFiles
.