React Nativeアプリをテスト
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.
セットアップ
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.
スナップショットテスト
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;
コンポーネントとのやり取りとレンダリングされた出力をキャプチャしてスナップショットファイルを作成するために、ReactのテストレンダラーとJestのスナップショット機能を利用しましょう:
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>
`;
次回のテストでは、レンダリングされた出力は前に作成されたスナップショットと比較されます。 スナップショットは、コードの変更に沿ってコミットされるべきです。 スナップショットテストが失敗した場合、それが意図的な変更かどうかを点検する必要があります。 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.
プリセット設定
プリセットは環境をセットアップしますが、それはとても偏っており Facebook において有用であるとわかったものをベースにしています。 ただ、すべての設定値は上書き可能でプリセットを使ってない場合でもそれに合わせて設定することができます。
環境
react-native ships with a Jest preset, so the preset field of your jest.config.js should point to react-native. プリセットは node 環境であり React Native アプリケーション環境を模倣します。 そのため一切の DOM や ブラウザ API をロードしないため、Jest の起動時間を大きく向上させます。
transformIgnorePatterns のカスタム
The transformIgnorePatterns option can be used to specify which files shall be transformed by Babel. Many react-native npm modules unfortunately don't pre-compile their source code before publishing.
By default the jest-react-native preset only processes the project's own source files and 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 by grouping them and separating them with the | operator:
{
"transformIgnorePatterns": ["node_modules/(?!((@)?react-native|my-project)/)"]
}
You can test which paths would match (and thus be excluded from transformation) with a tool like this.
transformIgnorePatterns will exclude a file from transformation if the path matches against any pattern provided. Splitting into multiple patterns could therefore have unintended results if you are not careful. In the example below, the exclusion (also known as a negative lookahead assertion) for foo and bar cancel each other out:
{
"transformIgnorePatterns": ["node_modules/(?!foo/)", "node_modules/(?!bar/)"] // not what you want
}
setupFiles
If you'd like to provide additional configuration for every test file, the setupFiles configuration option can be used to specify setup scripts.
moduleNameMapper
The moduleNameMapper can be used to map a module path to a different module. デフォルトではプリセットはすべてのイメージをイメージスタブモジュールにマップしていますがもしモジュールが見つからない場合はこの設定値が役立つかもしれません。
{
"moduleNameMapper": {
"my-module.js": "<rootDir>/path/to/my-module.js"
}
}