Hopp til hovedinnhold
Versjon: 30.0

Testing av React Native-apper

Unofficial Beta Translation

This page was AI-translated by PageTurner (beta). Not officially endorsed by the project. Found an error? Report issue →

På Facebook bruker vi Jest til å teste React Native-apper.

Få dypere innsikt i testing av en fungerende React Native-app ved å lese følgende artikler: Del 1: Jest – Snapshot-testing kommer i bildet og Del 2: Jest – Redux-snapshots for dine actions og reducers.

Oppsett

Fra og med react-native versjon 0.38 inkluderes en Jest-oppsett som standard når du kjører react-native init. Følgende konfigurasjon bør automatisk legges til i package.json-filen din:

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

Kjør yarn test for å utføre tester med Jest.

Hvis du oppgraderer React Native-applikasjonen din og tidligere brukte jest-react-native-presetet, fjern avhengigheten fra package.json-filen din og endre preset til react-native i stedet.

Snapshot-testing

La oss lage en snapshot-test for en liten intro-komponent med noen få views, tekstkomponenter og stiler:

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;

La oss nå bruke Reacts testrenderer og Jests snapshot-funksjon for å interagere med komponenten, fange den renderte outputen og opprette en snapshot-fil:

__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();
});

Når du kjører yarn test eller jest, vil dette produsere en output-fil som dette:

__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>
`;

Neste gang du kjører testene, vil den renderte outputen bli sammenlignet med forrige snapshot. Snapshotten bør committes sammen med kodeendringer. Når en snapshot-test feiler, må du undersøke om endringen er forventet eller utilsiktet. Hvis endringen er forventet, kan du kjøre Jest med jest -u for å overskrive det eksisterende snapshotet.

Koden for dette eksempelet finnes på examples/react-native.

Preset-konfigurasjon

Presetet konfigurerer miljøet og er svært meningsstyrt basert på det vi fant nyttig hos Facebook. Alle konfigurasjonsvalgene kan overstyres akkurat som de kan tilpasses når ingen preset brukes.

Miljø

react-native leveres med et Jest-preset, så jest.preset-feltet i package.json-filen din bør peke til react-native. Presetet er et node-miljø som etterligner miljøet i en React Native-app. Siden det ikke laster noen DOM- eller nettleser-APIer, forbedrer det betraktelig Jest oppstartstid.

Tilpasning av transformIgnorePatterns

Alternativet transformIgnorePatterns kan brukes til å spesifisere hvilke filer som skal transformeres av Babel. Mange react-native npm-moduler kompilerer dessverre ikke kildekoden før publisering.

Som standard prosesserer jest-react-native-presetet kun prosjektets egne kildefiler og react-native. Hvis du har npm-avhengigheter som må transformeres, kan du tilpasse dette konfigurasjonsalternativet ved å inkludere andre moduler enn react-native ved å gruppere dem og separere med |-operatoren:

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

Du kan teste hvilke filstier som vil matche (og dermed bli ekskludert fra transformasjon) med et verktøy som dette.

transformIgnorePatterns vil ekskludere en fil fra transformasjon hvis stien matcher hvilket som helst av de angitte mønstrene. Å dele opp i flere mønstre kan derfor gi utilsiktede resultater hvis du ikke er forsiktig. I eksempelet nedenfor opphever ekskluderingene (også kjent som negative lookahead-assertions) for foo og bar hverandre:

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

setupFiles

Hvis du ønsker å legge til ekstra konfigurasjon for hver testfil, kan du bruke konfigurasjonsalternativet setupFiles for å angi oppsettskript.

moduleNameMapper

moduleNameMapper kan brukes til å tilordne en modulsti til en annen modul. Som standard tilordner forhåndsinnstillingen alle bilder til en bilde-stubbmodul, men hvis en modul ikke kan finnes kan dette konfigurasjonsalternativet hjelpe:

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

Tips

Mock native moduler med jest.mock

Den innebygde Jest-forhåndsinnstillingen i react-native kommer med noen standard-mocks som brukes i et React Native-repositorium. Men noen React Native-komponenter eller tredjepartskomponenter er avhengige av at koden er rendret. I slike tilfeller kan Jests manuelle mock-system hjelpe deg med å mocke den underliggende implementasjonen.

For eksempel, hvis koden din avhenger av en tredjeparts native videokomponent kalt react-native-video, kan du stubbe den med en manuell mock slik:

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

Dette vil rendre komponenten som <Video {...props} /> med alle dens props i snapshot-utdataene. Se også begrensninger rundt Enzyme og React 16.

Noen ganger trenger du å tilby en mer kompleks manuell mock. For eksempel, hvis du ønsker å videresende prop-typene eller statiske felt av en native komponent til en mock, kan du returnere en annen React-komponent fra en mock gjennom denne hjelperen fra jest-react-native:

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

Eller hvis du ønsker å lage din egen manuelle mock, kan du gjøre noe som dette:

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;
});

I andre tilfeller kan det hende du vil mocke en innfødt modul som ikke er en React-komponent. Den samme teknikken kan brukes. Vi anbefaler å inspisere den innfødte modulens kildekode og loggføre modulen når du kjører en react native-app på en ekte enhet, og deretter modellere en manuell mock etter den virkelige modulen.

Hvis du gjentar å mocke de samme modulene om og om igjen, anbefales det å definere disse mockene i en egen fil og legge den til i listen over setupFiles.