Spec-Zone.ru › Jest

Тестирование приложений React Native

В Facebook мы используем Jest для тестирования приложений React Native.

Получите более глубокое понимание тестирования примера работающего приложения React Native, прочитав следующие серии: Часть 1: Jest – Снапшоты вступают в игру и Часть 2: Jest – Снапшоты Redux для ваших действий и редукторов.

Настройка

Начиная с версии react-native 0.38, настройка Jest включена по умолчанию при запуске react-native init. Следующая конфигурация должна быть автоматически добавлена в ваш файл package.json:

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

Примечание: если вы обновляете ваше приложение react-native и ранее использовали jest-react-native пресет, удалите зависимость из вашего файла package.json и измените пресет на react-native вместо этого.

Запустите yarn test для запуска тестов с помощью Jest.

Тест-снапшот

Давайте создадим тест-снапшот для небольшого вводного компонента с несколькими элементами представления и текстовыми компонентами, а также некоторыми стилями:

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;
Intro.js

Теперь давайте используем рендерер тестов 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();
});
__tests__/Intro-test.js

При запуске yarn test или jest, это создаст выходной файл, подобный этому:

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>
`;
__tests__/__snapshots__/Intro-test.js.snap

В следующий раз при запуске тестов отрендеренный вывод будет сравнен с ранее созданным снапшотом. Снапшот должен быть добавлен вместе с изменениями кода. Когда тест снапшота завершается неудачей, необходимо проверить, является ли это ожидаемым или непредвиденным изменением. Если изменение ожидается, вы можете вызвать Jest с jest -u для перезаписи существующего снапшота.

Код этого примера доступен по адресу examples/react-native.

Конфигурация пресета

Презет настраивает среду и является очень нацеленным, основанным на том, что оказалось полезным в Facebook. Все параметры конфигурации могут быть переопределены точно так же, как и могут быть настраиваемыми, когда пресет не используется.

Среда

react-native поставляется с пресетом Jest, поэтому поле jest.preset вашего файла package.json должно указывать на react-native. Пресет — это среда node, которая имитирует среду приложения React Native. Поскольку он не загружает никаких DOM или API браузера, это значительно улучшает время запуска Jest.

Настройка transformIgnorePatterns

Параметр transformIgnorePatterns может быть использован для указания файлов, которые будут преобразованы Babel. Многие react-native модули npm, к сожалению, не предварительно компилируют свой исходный код перед публикацией.

По умолчанию пресет jest-react-native обрабатывает только собственные исходные файлы проекта и react-native. Если у вас есть зависимости npm, которые необходимо преобразовать, вы можете настроить этот параметр конфигурации, включив модули, отличные от react-native, группируя их и разделяя их оператором |.

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

Вы можете проверить, какие пути будут соответствовать (и, следовательно, будут исключены из преобразования) с помощью инструмента такого как этот.

transformIgnorePatterns исключит файл из преобразования, если путь соответствует любому предоставленному шаблону. Разделение на несколько шаблонов может, следовательно, привести к непредвиденным результатам, если вы не будете внимательны. В примере ниже исключение (также известное как отрицательное предпросмотрное утверждение) для foo и bar взаимно аннулируются:

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

setupFiles

Если вы хотите предоставить дополнительную конфигурацию для каждого файла теста, можно использовать параметр конфигурации setupFiles для указания скриптов настройки.

moduleNameMapper

moduleNameMapper может быть использован для сопоставления пути модуля с другим модулем. По умолчанию пресет сопоставляет все изображения с модулем-заглушкой изображения, но если модуль не найден, этот параметр конфигурации может помочь:

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

Советы

Моделирование нативных модулей с помощью jest.mock

Презет Jest, встроенный в react-native, поставляется с несколькими модулями-заглушками по умолчанию, которые применяются к репозиторию react-native. Однако некоторые компоненты react-native или компоненты сторонних разработчиков полагаются на нативный код для рендеринга. В таких случаях система ручного моделирования Jest может помочь смоделировать реализацию.

Например, если ваш код зависит от стороннего нативного компонента видео под названием react-native-video, вы можете заменить его ручным моделированием, как показано ниже:

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

Это отобразит компонент как <Video {...props} /> со всеми его параметрами в выходном файле снапшота. См. также ограничения, связанные с Enzyme и React 16.

Иногда вам нужно предоставить более сложное ручное моделирование. Например, если вы хотите передать типы свойств или статические поля нативного компонента в модель, вы можете вернуть другой компонент React из модели с помощью этого помощника из jest-react-native:

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

Или, если вы хотите создать свою собственную ручную модель, вы можете сделать что-то вроде этого:

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

В других случаях вам может потребоваться смоделировать нативный модуль, который не является компонентом React. Та же техника может быть применена. Мы рекомендуем изучить исходный код нативного модуля и выполнить протоколирование модуля при запуске приложения react native на реальном устройстве, а затем смоделировать ручную модель по образцу реального модуля.

Если вы постоянно моделируете одни и те же модули, рекомендуется определить эти модели в отдельном файле и добавить его в список setupFiles.

© 2022 Facebook, Inc.
Licensed under the MIT License.
https://jestjs.io/docs/tutorial-react-native

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API