Testing React Native Apps
At Facebook, we use Jest to test React Native applications.
Get a deeper insight into testing a working React Native app example by reading the following series:
- Part 1: Jest – Snapshot come into play
- Part 2: Jest – Redux Snapshots for your Actions and Reducers.
Setup
Starting from react-native version 0.38, a Jest setup is included by default when running npx @react-native-community/cli init. The following configuration should be automatically added to your React Native's jest.config.js file:
module.exports = {
preset: 'react-native',
};
Run yarn test to run tests with Jest.
If you are upgrading your react-native application and previously used the jest-react-native or react-native preset, remove the dependency from your package.json file and change the preset to react-native in jest.config.js instead.
Snapshot Test
Let's create a snapshot test for a small intro component with a few views and text components and some styles:
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;
Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file:
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:
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>
`;
The next time you run the tests, the rendered output will be compared to the previously created snapshot. The snapshot should be committed along with code changes. When a snapshot test fails, you need to inspect whether it is an intended or unintended change. If the change is expected you can invoke Jest with jest -u to overwrite the existing snapshot.
The code for this example is available at examples/react-native.
Preset configuration
The preset sets up the environment and is very opinionated and based on what we found to be useful at Facebook. All of the configuration options can be overwritten just as they can be customized when no preset is used.