Тесування React Native додатків
Facebook використовує Jest для тестування додатків React Native.
Поглиблену інформації про приклад тестування працюючого додатку React Native можна знайти в наступних джерелах: Part 1: Jest – Snapshot come into play та Part 2: Jest – Redux Snapshots for your Actions and Reducers.
Налаштування
Починаючи з react-native версії 0.38, налаштування Jest включено за замовчуванням при запуску react-native init
. Наступні налаштування пови нні бути автоматично додані у ваш файл package.json:
{
"scripts": {
"test": "jest"
},
"jest": {
"preset": "react-native"
}
}
Run yarn test
to run tests with Jest.
Якщо ви оновлюєте в аш react-native додаток і раніше використовували пресет jest-react-native
, видаліть залежність з вашого файлу package.json
та замініть пресет на react-native
.
Тест зі знімком
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>
`;
Наступного разу, під час запуску тестів, результат роботи компонента буде порівняний зі збереженим знімком. The snapshot should be committed along with code changes. Коли тест, що використовує знімки, провалиться, вам потрібно буде перевірити чи відбулися навмисні, чи ненавмисні зміни. Якщо зміни були очікувані, ви можете запустити Jest командою jest -u
, щоб оновити існуючі знімки.
The code for this example is available at examples/react-native.
Конфігурація пресету
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.
Середовище
react-native
ships with a Jest preset, so the jest.preset
field of your package.json
should point to react-native
. The preset is a node environment that mimics the environment of a React Native app. Because it doesn't load any DOM or browser APIs, it greatly improves Jest's startup time.
Налаштування 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|react-native-button)/)"
]
}
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/)"] // не те, що потрібно
}
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. By default the preset maps all images to an image stub module but if a module cannot be found this configuration option can help:
{
"moduleNameMapper": {
"my-module.js": "<rootDir>/path/to/my-module.js"
}
}