Модульное тестирование - это здорово, тестирование моментальных снимков тоже отлично, но из моей практики лучшие тесты - это те, которые тестируют как бэкэнд, так и фронт (Integration Test). - Григорий Пташко
Так как же выглядит интеграционный тест Relay?
Этот тест заставит контейнеры Relay делать реальные запросы к работающему бэкэнду GraphQL.
Исходный код этого сообщения: https://github.com/sibelius/relay-integration-test (наслаждайтесь как React Web, так и React Native).
Рабочий сервер GraphQL: https://github.com/sibelius/graphql-dataloader-boilerplate
Мотивация
Интеграционные тесты Relay - это самый простой способ убедиться, что вы обнаружите любой сломанный компонент или код, когда вы изменяете свой бэкэнд GraphQL или интерфейсное приложение Relay с помощью React или React Native.
Способ заставить это работать
Эта идея была предложена https://github.com/GrigoryPtashko по этим двум вопросам: facebook / relay # 1281 и facebook / jest # 1898
Я начал копаться в тестировании Jest и понял, что проблема в том, что fetch не полифицируется в среде Jest (facebook / jest # 2071)
Для React Native мне нужно выполнить полифил XMLHttpRequest, чтобы он заработал (sibelius / relay-integration-test)
Для React Web мне нужно выполнить полифил-выборку (sibelius / relay-integration-tes t)
Итоговые тесты выглядят так:
import 'react-native'; import React from 'react'; import Relay from 'react-relay'; import App from '../app'; import RelayStore from '../RelayStore'; // Note: test renderer must be required after react-native. import renderer from 'react-test-renderer'; RelayStore.reset( new Relay.DefaultNetworkLayer('http://localhost:5000/graphql') ); const delay = (value) => new Promise(resolve => setTimeout(() => resolve(), value) ); it('renders correctly', async () => { const tree = renderer.create( <App /> ); // Wait Relay to fetch data await delay(3000); expect(tree.toJSON()).toMatchSnapshot(); });
Этот тест визуализирует компонент ‹App /›, который является контейнером Relay.Renderer, используя react-test-renderer, затем он будет ждать 3 секунды, чтобы позволить Relay получить необходимые данные, затем мы делаем снимок компонента результата
Шаг за шагом
- Добавьте Jest в свой проект
yarn add jest jest-cli react-test-renderer --dev
Для React Web (полифил выборки)
yarn add isomorphic-fetch --dev
Для React Native (предустановка react native jest и полифилл XMLHttpRequest)
yarn add jest-react-native xhr2 --dev
2. Добавьте конфигурацию Jest в свой package.json.
Для React Web
"jest": { "setupFiles": [ "./test/env.js" ] }, "scripts": { "test": "jest" }
Для React Native
"jest": { "preset": "jest-react-native", "setupFiles": [ "./test/env.js" ] }, "scripts": { "test": "jest" }
3. Создайте файл env.js (настройка тестовой среды).
Для React Web
import 'isomorphic-fetch';
Для React Native
const XMLHttpRequest = require('xhr2'); global.XMLHttpRequest = XMLHttpRequest;
4. Создайте компонент Relay Container для тестирования.
import React, { Component } from 'react'; import { StyleSheet, Text, View, } from 'react-native'; import Relay from 'react-relay'; import ViewerQuery from './ViewerQuery'; import { createRenderer } from './RelayUtils'; import RelayStore from './RelayStore'; RelayStore.reset( new Relay.DefaultNetworkLayer('http://localhost:5000/graphql') ); class RelayApp extends Component { render() { return ( <View> <Text>name: {this.props.viewer.users.edges[0].node.name}</Text> <Text>length: {this.props.viewer.users.edges.length}</Text> </View> ); } } // Create a Relay.Renderer container export default createRenderer(RelayApp, { queries: ViewerQuery, fragments: { viewer: () => Relay.QL` fragment on Viewer { users(first: 2) { edges { node { name } } } } `, }, });
createRenderer - это вспомогательная функция, которая легко создаст для вас Relay.Renderer (проверьте файл здесь: https://gist.github.com/janicduplessis/f513032eb37cdde5d050d9ce8cf0b92a)
Для Интернета я адаптировал версию createRenderer - https://github.com/sibelius/relay-integration-test/blob/master/RelayWeb/src/RelayUtils.js
5. Создайте первый тест интеграции реле.
import 'react-native'; import React from 'react'; import Relay from 'react-relay'; import App from '../app'; import RelayStore from '../RelayStore'; import renderer from 'react-test-renderer'; RelayStore.reset( new Relay.DefaultNetworkLayer('http://localhost:5000/graphql') ); const delay = (value) => new Promise(resolve => setTimeout(() => resolve(), value) ); it('renders correctly', async () => { const tree = renderer.create( <App /> ); // Wait Relay to fetch data await delay(3000); expect(tree.toJSON()).toMatchSnapshot(); });
6. Запустите сервер GraphQL.
Я использую graphql-dataloader-template (https://github.com/sibelius/graphql-dataloader-boilerplate) в качестве тестового сервера. Просто запустите следующую команду, чтобы запустить ее
yarn run watch
7. Начните тесты.
yarn test
или проще:
jest
Совет: при написании теста вы можете использовать следующую команду для автоматического отслеживания изменений в файле, над которым вы работаете:
jest TestFileName --watch
Спасибо Григорию Пташко за эту замечательную идею.
Что дальше
- Проверка мутаций реле
- Тестирование изменения поведения переменных реле
Ресурсы
Вы также должны провести модульное тестирование своего GraphQL Backend
Вы также должны сделать свой GraphQL Backend безопасным -
Оформить заказ на мой шаблон GraphQL + DataLoader с 95% покрытием кода
Возникли проблемы с React Native + Relay - проверьте этот стартовый код:
Пытаюсь использовать ex-navigation с Relay - приступайте к работе
Новостная рассылка
Подпишитесь на мою рассылку для получения нового контента https://sibelius.substack.com/