Тестирование компонентов React: Руководство по основным вопросам (2019)

  1. Тестирование компонентов React: необходимость разработки через тестирование
  2. Тестирование компонентов React: для кого предназначено это руководство
  3. Тестирование компонентов React: чему вы научитесь
  4. Тестирование компонентов React: знакомство с тестированием моментальных снимков
  5. Тестирование компонентов React: руки на рэк-тест-рендерер
  6. Тестирование компонентов React: неправильное тестирование (не тестируйте реализацию)
  7. Тестирование компонентов React: правильное тестирование компонентов (тестирование с точки зрения пользователя)...
  8. Тестирование компонентов React: тестирование парных и фиктивных
  9. Тестирование компонентов React: насмешливый аксиос с шуткой
  10. Тестирование компонентов React: заглушение ответов с помощью Cypress

Живое руководство по тестированию компонентов React. Постоянно обновляется, лучше вы в закладки! Живое руководство по тестированию компонентов React

Веб-разработка фантастическая! Вы знаете HTML, CSS, JavaScript и React! Вы готовы создавать фантастические веб-приложения, которые люди будут использовать и любить! Это звучит как сон ... пока вы не получите свою первую работу в качестве фронт-разработчика .

Я не хочу вас пугать, но представьте это.

Молли, ведущий разработчик, знакомит вас с проектом после краткой экскурсии по офисам. Она объясняет, как работает приложение, и в какой-то момент говорит:

«Хорошо, Гуннар, вот твоя задача. Мы находимся в процессе восстановления приложения. Я хочу, чтобы вы переписали это с нуля. Но я хочу, чтобы вы следовали подходу TDD. Вы должны написать хороший набор тестов для этого проекта ».

Вы паникуете. TDD ? Тестовый пакет? Вам знакома эта история?

Тестирование компонентов React: необходимость разработки через тестирование

В этот момент вы можете спросить: зачем нам тестировать наши компоненты React ? Почему мы должны тестировать наши приложения с первого взгляда?

Все замечательно, пока вы не поиграете с React самостоятельно. Но как только вы попадете в реальный мир, у вас будут проблемы. Я сосредоточен на React, но на самом деле это может быть любая другая библиотека или фреймворк.

Как сказал Джейкоб Каплан-Мосс: «Код без тестов нарушен замыслом».

Бьюсь об заклад, это так! Я бы также сказал: в веб-приложении без тестов ваши пользователи будут бета-тестерами .

Ты согласен с этим? Потому что я нет. Доверяете ли вы непроверенному коду от других разработчиков?

Я знаю, что вы потратили месяцы на изучение основ React, и теперь вы чувствуете, что ничего не сделали. Проблема в том, что большинство курсов и учебных пособий не дают **** о тестировании . Если вы узнали основы React, не останавливайтесь на достигнутом.

Начните задавать себе эти вопросы:

Как проверить React и Redux в рамках проекта ?

Что такое приемочные испытания ? Знаю ли я что-нибудь о двухконтурном TDD ?

Это может звучать как пропаганда, но я гарантирую, что это не так. Без этих навыков невозможно выжить на рынке. Итак, вот живое, дышащее руководство по всем испытаниям в React.

Приятного чтения!

Тестирование компонентов React: для кого предназначено это руководство

Если у вас есть общее представление о React, то это руководство для вас.

Я предлагаю также потратить некоторое время на изучение теории вокруг рамки тестирования а также Тест-управляемая разработка ,

В этом руководстве я предполагаю, что вы знаете, что такое Jest и что делает среда тестирования.

Тестирование компонентов React: чему вы научитесь

В этом руководстве вы узнаете, как:

  • модульное тестирование компонентов React
  • функциональное тестирование в приложениях React

и многое другое!

Тестирование компонентов React: знакомство с тестированием моментальных снимков

Одним из самых простых способов тестирования компонентов React является тестирование снимков .

Снимки - это распространенная тема в технологии: вы можете сделать снимок виртуального частного сервера. Или вы можете сделать снимок тома в AWS.

И так далее.

Тестирование снимков в React не встроено в саму библиотеку: вместо этого это особенность, встроенная в Jest ,

Тестирование моментальных снимков больше ориентировано на тестирование пользовательского интерфейса, но некоторые люди используют моментальные снимки для тестирования кода JavaScript (этот подход мне не нравится).

Итак, как работает тестирование снимков ?

Jest (участник тестирования) делает снимок компонента при первом запуске , а затем проверяет, соответствует ли сохраненный снимок фактическому компоненту .

Как выглядит тест снимка ?

Для тестирования моментального снимка компонента React вы можете создать новый файл в папке с именем __tests__ внутри папки src вашего проекта.

Jest будет искать там новые тесты для запуска.

Затем в тестовом файле вы должны импортировать React, реагирует тест-рендерер и компонент, который вы хотите проверить.

А вот пример тестирования снимков:

импорт React из "реакции"; import {create} из "act-test-renderer "; импортировать FeatureComponent из "../FeatureComponent"; description ("Компонент Feature", () => {test ("он соответствует снимку", () => {const component = create (<FeatureComponent />); ожидаем (component.toJSON ()). toMatchSnapshot (); });});

Но давайте немного разберемся. Что такое « рендеринг-тест-рендерер» ?

response-test-renderer - библиотека для визуализации компонентов React в чистых объектах JavaScript. Угадайте, что это хороший способ для тестирования наших компонентов самым простым способом.

А что такое создание ? create - это метод от response-test-renderer для «монтирования» компонента.

Ну, компонент не монтируется, как вы могли ожидать . Вместо этого create создает экземпляр компонента , с которым вы можете делать утверждения.

Ничего не стоит, что рендерит-тест-рендерер не использует настоящий DOM .

Это имеет смысл, компонент не монтируется, но вместо этого создается его чистое JavaScript-представление.

Далее в нашем тесте есть toMatchSnapshot который является методом, предоставленным Jest.

toMatchSnapshot работает следующим образом:

  • он создает снимок компонента, если его нет
  • он проверяет, соответствует ли компонент сохраненному снимку

На данный момент один из наиболее частых вопросов: как выбрать между тестированием моментальных снимков и другими типами тестирования в React ?

У меня есть одно правило: часто ли меняется ваш компонент? Если это так, избегайте тестирования снимков .

Если вы сделаете снимок компонента, тест пройден. Но что происходит, когда вы модифицируете компонент?

Тест не пройден. И вам придется удалить снимок. Это не похоже на большое дело, но ...

Как вы можете догадаться, тесты моментальных снимков хороши для компонентов, которые меняются не часто.

Иными словами, подумайте о написании теста снимка, когда вы уверены, что компонент стабилизирован .

А теперь давайте подробнее рассмотрим рендеринг реагирующих тестов!

Тестирование компонентов React: руки на рэк-тест-рендерер

response-test-renderer - библиотека для визуализации компонентов React в чистых объектах JavaScript.

Но похоже, что response-test-renderer может сделать гораздо больше, чем создавать объекты . Фактически мы можем использовать response-test-renderer для подтверждения поведения наших компонентов .

Допустим, мы хотим создать компонент кнопки.

Кнопка должна изменить свой текст с «ПОДПИСАТЬСЯ НА ОСНОВНОЙ» на «ПРОДОЛЖИТЬ ПРОВЕРИТЬ» при нажатии.

Поскольку мы занимаемся разработкой на основе тестов, дисциплина заставляет вас написать провальный тест, прежде чем делать что-либо еще .

Похоже, что в компоненте есть минимальная логика. Это может иметь состояние тоже.

Это означает, что тест снимка не будет нашим лучшим выбором . Мы хотим протестировать методы и логику для нашего компонента. Как бы вы пошли об этом?

Reaction-test-renderer может помочь нам протестировать такие компоненты.

Давайте посмотрим, как в следующем разделе!

Тестирование компонентов React: неправильное тестирование (не тестируйте реализацию)

Нам нужен компонент кнопки для нашего приложения.

Кнопка должна изменить свой текст с «ПОДПИСАТЬСЯ НА ОСНОВНОЙ» на «ПРОДОЛЖИТЬ ПРОВЕРИТЬ» при нажатии.

Давайте создадим новый тест в __tests __ / Button.spec.js:

// Button.spec.js import React из "реакция"; import {create} из "act-test-renderer "; Кнопка импорта из "../Button"; description ("Компонент Button", () => {test ("показывает ожидаемый текст при нажатии (тестирование неверно!)", () => {//});});

Как вы можете видеть, я обозначил тест как «неправильный тест».

Почему так?

Поскольку мы тестируем компонент с состоянием (компонент React с его собственным состоянием), мы, естественно, испытываем желание протестировать его внутреннюю реализацию .

Посмотрим.

Мы создадим экземпляр компонента с Создайте ,

Далее мы будем получить этот экземпляр для утверждения о его внутреннем состоянии .

Я ожидаю, что свойство text состояния будет пустым:

// Button.spec.js import React из "реакция"; import {create} из "act-test-renderer "; Кнопка импорта из "../Button"; description ("Компонент кнопки", () => {test ("показывает ожидаемый текст при нажатии (тестирование неверным образом!)", () => {const component = create (<Button text = "ПОДПИСАТЬСЯ НА ОСНОВНОЙ" />); const instance = component.getInstance (); ожидается (instance.state.text) .toBe ("");});});

Если я запустил тест с npm, он потерпит неудачу, потому что я еще не создал компонент .

Давайте сделаем это! Вот минимальная реализация для компонента кнопки:

класс экспорта по умолчанию Button extends Component {constructor (props) {super (props); this.state = {text: ""}; this.handleClick = this.handleClick.bind (this); } handleClick () {this.setState (this.stateUpdater); } stateUpdater () {return {text: "ПРОДОЛЖИТЬ ПРОВЕРИТЬ"}; } render () {return (<button onClick = {this.handleClick}> {this.state.text || this.props.text} </ button>); }}

Теперь, если я снова запускаю тест, он проходит .

До этого момента я еще не все тестировал: как насчет handleClick? Даже если это плохая практика, как я могу проверить внутренние методы на моих компонентах React?

С помощью response-test-renderer мы можем вызывать методы в нашем экземпляре.

Давайте обновим наш тест:

// Button.spec.js import React из "реакция"; import {create} из "act-test-renderer "; Кнопка импорта из "../Button"; description ("Компонент кнопки", () => {test ("показывает ожидаемый текст при нажатии (тестирование неверным образом!)", () => {const component = create (<Button text = "ПОДПИСАТЬСЯ НА ОСНОВНОЙ" />); const instance = component.getInstance (); ожидать (instance.state.text) .toBe (""); instance.handleClick (); ожидать (instance.state.text) .toBe ("ПРОДОЛЖИТЬ ПРОВЕРИТЬ" );});});

Обратите внимание, как я могу сказать:

instance.handleClick ();

и тогда я могу утверждать, что состояние компонента изменяется, как и ожидалось:

Ожидайте (instance.state.text) .toBe («ПРОДОЛЖИТЬ ПРОВЕРИТЬ»);

Если я снова запускаю тест, он все равно проходит.

Но вы можете увидеть ловушку в этом тесте ?

Вы можете попробовать самостоятельно: удалите кнопку из метода рендеринга компонента. Измените инструкцию возврата и верните ноль . Запустите тест снова и ... вы можете видеть, что он все еще проходит !

Тестируем ли мы компонент с точки зрения пользователя ? Нет Я понятия не имею, будет ли моя кнопка отображать правильный текст для моих пользователей .

Есть ли способ проверить это?

Тестирование компонентов React: правильное тестирование компонентов (тестирование с точки зрения пользователя)

Тестирование внутренней реализации объекта всегда плохая идея .

Это верно для React, JavaScript и для любого языка программирования. Вместо этого мы можем протестировать компонент с точки зрения пользователя .

Например, в двухконтурном TDD разработка ведется с помощью функционального теста. Функциональное тестирование или сквозное тестирование - это способ тестирования веб-приложений с точки зрения пользователя.

(Существует много путаницы и дублирования в терминологии тестирования. Я предлагаю провести некоторое собственное исследование, чтобы узнать больше о различных типах тестирования. Для целей данного руководства функциональное тестирование === сквозное тестирование ).

Для функционального тестирования я склонен использовать кипарис много.

Но сейчас мы можем получить тот же результат на уровне модуля с помощью рендеринга-теста-рендеринга . Давайте посмотрим, как провести рефакторинг нашего теста.

Мы оставили здесь:

// Button.spec.js import React из "реакция"; import {create} из "act-test-renderer "; Кнопка импорта из "../Button"; description ("Компонент кнопки", () => {test ("показывает ожидаемый текст при нажатии (тестирование неверным образом!)", () => {const component = create (<Button text = "ПОДПИСАТЬСЯ НА ОСНОВНОЙ" />); const instance = component.getInstance (); ожидать (instance.state.text) .toBe (""); instance.handleClick (); ожидать (instance.state.text) .toBe ("ПРОДОЛЖИТЬ ПРОВЕРИТЬ" );});});

Мы протестировали внутреннюю реализацию компонента, напрямую вызвав handleClick.

Мы полностью обошли реквизиты нашей кнопки onClick :

<button onClick = {this.handleClick}> {this.state.text || this.props.text} </ button>

И мы не тестировали то, что должен видеть пользователь.

Можем ли мы сделать лучше?

Оказывается, мы можем использовать testRenderer.root вместо .getInstance ():

// Button.spec.js import React из "реакция"; import {create} из "act-test-renderer "; Кнопка импорта из "../Button"; description ("Компонент кнопки", () => {test ("при нажатии отображается ожидаемый текст", () => {const component = create (<Button text = "SUBSCRIBE TO BASIC" />); const rootInstance = component.root;});});

Согласно документации testRenderer.root «возвращает объект экземпляра корневого теста, который полезен для создания утверждений о конкретных узлах в дереве».

Давайте тогда найдем нашу кнопку!

Мы можем сказать:

const button = rootInstance.findByType ("button");

И оттуда я наконец могу получить доступ к кнопке реквизита:

button.props.onClick ();

И последнее, но не менее важное: я могу стучать в кнопку реквизита

button.props.children

И вот полный тест:

// Button.spec.js import React из "реакция"; import {create} из "act-test-renderer "; Кнопка импорта из "../Button"; description ("Компонент кнопки", () => {test ("при нажатии отображается ожидаемый текст", () => {const component = create (<Button text = "SUBSCRIBE TO BASIC" />); const rootInstance = component.root; const button = rootInstance.findByType ("button"); button.props.onClick (); ожидание (button.props.children) .toBe ("ПРОДОЛЖИТЬ ПРОВЕРИТЬ");});});

Как это выглядит? Намного лучше, чем в предыдущем тесте, когда мы тестировали состояние компонента.

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

Но пока все хорошо: мы наконец протестировали то, что должен видеть пользователь, а не состояние внутреннего компонента, как мы делали раньше .

Помните: при тестировании компонента с состоянием (компонента React с его собственным состоянием) у вас может возникнуть желание проверить его внутреннее состояние.

Не делай этого .

Вы можете выбрать другой путь: тестирование вывода компонента.

Не тестируйте реализацию: протестируйте компонент с точки зрения пользователя . Другими словами: проверьте, что должен видеть пользователь.

Тестирование компонентов React: тестирование парных и фиктивных

Извлечение и отображение данных - один из самых распространенных вариантов использования интерфейсной библиотеки. Обычно это делается путем обращения к внешнему API, который содержит для нас некоторый JSON.

В React вы будете использовать метод жизненного цикла componentDidMount для выполнения вызова AJAX, как только компонент монтируется.

Вы также можете использовать async / await для componentDidMount (хотя есть некоторые оговорки).

Теперь дело в том, как вы тестируете AJAX-вызов в React ? Должны ли вы сделать вызов действующему API? Может быть! Но возникают некоторые вопросы.

Учтите это: ваша команда проводит автоматическое тестирование в среде CI / CD. Команда принимает участие в основной ветке 3/4 раза в день.

Что произойдет, если API выйдет из строя? Тесты не пройдут без всякой причины.

А что будет, если каждый вызов API стоит денег ?

Очевидно, что контакт с реальным API во время тестирования далеко не оптимален . Так? Какое решение?

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

Например, мы можем заменить внешнюю систему фальшивкой на этапе тестирования. С момента появления современных фреймворков для тестирования мы можем даже макетировать функции .

Насмешка - это акт замены действительной функции поддельной копией . Чтобы узнать больше о насмешках и заглушках, ознакомьтесь TestDouble от Жерара Месароса ,

А пока мы сосредоточимся на насмешливых запросах GET в Axios . Axios - одна из самых популярных библиотек для выполнения запросов AJAX, а с помощью Jest вы можете высмеивать ее функциональность.

Давайте посмотрим, как смоделировать .get, который является методом axios для выполнения запросов GET.

СОВЕТ : получать является действительной, нативной альтернативой axios, хотя в ней отсутствуют некоторые функции. В наши дни я все еще предпочитаю axios, а не fetch из-за его тестируемости . На самом деле на момент написания этой статьи Cypress не поддерживает заглушки для получения ,

Тестирование компонентов React: насмешливый аксиос с шуткой

Опять давайте начнем с теста .

Предположим, нам нужен компонент «Пользователи» для извлечения и отображения списка пользователей .

Наивная реализация может использовать async / await в componentDidMount (хотя это плохая идея).

Это означает, что при создании нашего теста мы можем ожидать на componentDidMount .

Вот скелет нашего теста:

импорт React из "реакции"; import {create} из "act-test-renderer "; импортировать пользователей из "../Users"; description ("Компонент Users", () => {it ("показывает список пользователей", async () => {const component = create (<Users />); const instance = component.getInstance (); ожидайте экземпляр .componentDidMount (); //});});

Вы должны быть уже знакомы с create и getInstance из Reaction-Test-Renderer.

Обратите внимание, как вы можете использовать async / await в Jest.

Вы, наверное, видели нечто подобное в моем предыдущем посте, когда я освещал тестирование коа с Jest и Supertest ,

Также стоит отметить в приведенном выше примере: я вызываю componentDidMount в тестируемом экземпляре .

Теперь, если я запускаю тест npm, вышеуказанный тест не пройден, потому что я еще не создал компонент.

Лучше мы сделаем минимальную реализацию для этого!

Это может быть компонент с отслеживанием состояния, который получает данные от удаленного API с Axios, а затем отображает такие данные для наших пользователей :

импортировать React, {Component} из "реакции"; импорт axios из "axios"; класс экспорта по умолчанию. Пользователь расширяет Компонент {конструктор (props) {супер (props); this.state = {data: []}; this.handleGet = this.handleGet.bind (this); } handleGet (response) {this.setState (this.stateUpdater (response)); } stateUpdater (response) {return {data: response.data}; } async componentDidMount () {const response = await axios.get ("https://jsonplaceholder.typicode.com/users"); this.handleGet (ответ); } render () {return (<ul> {this.state.data.map (user => (<li key = {user.name}> {user.name} </ li>))} </ ul>) ; }}

Ничего нового, а?

Я не смог устоять перед использованием async / await на componentDidMount, но давайте поясним: это плохая практика. Вы всегда должны перемещать асинхронную логику из компонентов React .

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

Должен признаться, я тоже не могу устоять перед console.log.

Вы в порядке, если я стучу в состояние моего тестового экземпляра?

импорт React из "реакции"; import {create} из "act-test-renderer "; импортировать пользователей из "../Users"; description ("Компонент Users", () => {it ("показывает список пользователей", async () => {const component = create (<Users />); const instance = component.getInstance (); ожидайте экземпляр .componentDidMount (); console.log (instance.state) // << ЗДЕСЬ НУЖДА!});});

Сюрприз! После запуска instance.componentDidMount () я вижу, как обновляется новое состояние !

Есть также что-то вроде JSON от jsonplaceholder.typicode.com.

Мы назвали настоящий API !

Это нормально? Короче нет . Вы никогда не должны вызывать настоящий API во время тестирования .

Если API замедлится, ваши автоматизированные тесты пострадают и сломаются .

Если API выйдет из строя, ваши тесты тоже будут сломаны .

Если API платный, с вас будет взиматься плата каждый раз при запуске теста npm .

Хорошо, я продал Валентино! Я очень хочу издеваться над аксиосами ! Что теперь?

Шутка делает насмешливый Аксиос легким как ветер .

Для насмешливого axios.get мы должны:

импорт Axios внутри нашего теста

использование jest.mock для издевательства над модулем axios

предоставить пользовательский ответ для axios.get

использование mockResolvedValue для подделки асинхронного ответа

Давай сделаем это:

импорт React из "реакции"; import {create} из "act-test-renderer "; импортировать пользователей из "../Users"; импорт axios из "axios"; jest.mock ( "Вардар"); description ("Компонент Users", () => {it ("показывает список пользователей", async () => {const response = {data: [{name: "Kevin Mitnick"}, {name: "Valentino Gagliardi "}]}; axios.get.mockResolvedValue (response); const component = create (<Users />); const instance = component.getInstance (); await instance.componentDidMount (); console.log (instance.state); // << ЗДЕСЬ СНИТЧ!});});

Если вы снова посмотрите на instance.state после запуска теста, вы увидите поддельные данные внутри состояния:

state после запуска теста, вы увидите поддельные данные внутри состояния:

Мы преуспели в насмешках !

Теперь мы можем завершить наш тест с некоторыми утверждениями (и удалить console.log).

Мы хотим проверить, что наши пользователи эффективно видят 2 элемента li из этого компонента React.

Если вы помните, при тестировании компонентов React нам не нужно заботиться о внутреннем состоянии .

Мы заинтересованы в тестировании того, что должен видеть пользователь .

Для прохождения теста я хочу найти все элементы li, утверждая ожидаемое содержание текста:

импорт React из "реакции"; import {create} из "act-test-renderer "; импортировать пользователей из "../Users"; импорт axios из "axios"; jest.mock ( "Вардар"); description ("Компонент Users", () => {it ("показывает список пользователей", async () => {const response = {data: [{name: "Kevin Mitnick"}, {name: "Valentino Gagliardi "}]}; axios.get.mockResolvedValue (response); const component = create (<Users />); const instance = component.getInstance (); await instance.componentDidMount (); const root = component.root; const listOfLi = root.findAll (element => element.type === "li"); ожидаемо (listOfLi [0] .props.children) .toBe ("Кевин Митник"); ожидаемо (listOfLi [1] .props.children) .toBe ("Валентино Гальярди");});});

Обратите внимание на использование component.root и findAll, вызываемых в корневом экземпляре.

Теперь тест проходит! Фантастика.

Какой вынос из этого раздела?

При возможности не стоит называть настоящий API в автоматическом тестировании. В идеале тесты не должны зависеть от внешних систем . Посмеиваясь над осями и предоставляя ложный ответ, мы обеспечиваем изоляцию теста .

Но подделка ответа от API тоже имеет свои недостатки. Если бы я изменил URL-адрес в componentDidMount следующим образом:

async componentDidMount () {const response = await axios.get ("https://blablabala.typicode.com/users"); this.handleGet (ответ); }

как вы думаете, что происходит? Испытание будет проходить до тех пор, пока я буду издеваться над аксио с поддельным ответом. Но я не увижу ни одного пользователя, если открою приложение в браузере. Код работает в тестировании, но не в «производстве» . Насмешка и подделка действительно полезны, но есть некоторые компромиссы.

В следующем разделе мы увидим, как заглушить ответ API в функциональном тесте. Помните, что функциональное тестирование движет нашей разработкой.

СОВЕТ : не забудьте вернуть обещание от axios, если вы предпочитаете использовать axios.get (). Then () в componentDidMount. В противном случае вы не сможете проверить это:

componentDidMount () {возврат axios.get (someurl) .then (doStuff) .catch (handleErr)}

СОВЕТ : выполнение асинхронных вызовов в componentDidMount считается плохой практикой. Рассмотрим всегда перемещение асинхронной логики из компонентов React , Хорошее место для такого рода вещей - промежуточное ПО Redux.

Тестирование компонентов React: заглушение ответов с помощью Cypress

В этом руководстве мы сразу начали с юнит-тестов, но я должен был сделать наоборот. В Double-loop TDD это функциональное тестирование, которое движет нашей разработкой. Мы пишем функциональный тест для проверки того, что наше приложение удовлетворяет некоторым пользовательским историям. Когда функциональный тест не пройден, мы переходим к написанию модульных и интеграционных тестов, которые, в свою очередь, определяют способ кодирования наших компонентов.

Не секрет, что я люблю Cypress за функциональное тестирование. В этом разделе я покажу вам, как заглушить ответ от внешнего API.

В предыдущем разделе мы подделали ответ от axios.get. То, как мы это делаем, - это издевательство над аксиосами. То есть издевательство означает замену реальной функции подделкой . Заглушка немного отличается. Когда я говорю о заглушении ответов, это означает отключение реального API . Как мы это делаем в Cypress?

(Прежде чем двигаться дальше, я предлагаю глядя на мой учебник Cypress для изучения синтаксиса в кипарисе).

Предположим, я хочу написать небольшой функциональный тест для моего компонента. Это может начаться так:

description ("Some APP", () => {it ("как пользователь, я вижу список людей", () => {cy.visit ("/"); cy.contains ("Valentino Gagliardi") ;});});

Этот тест сразу провалится, потому что мой компонент React вызывает настоящий API :

Cypress достаточно умен, чтобы дать мне подсказку: обратите внимание на изображение XHR (XMLHttpRequest). Как я могу избежать вызова реального API?

Cypress дает вам два мощных инструмента. Все, что мне нужно сделать, это вызвать cy.server и cy.route перед посещением страницы:

description ("Some APP", () => {it ("как пользователь, я вижу список людей", () => {cy.server (); cy.route ({method: "GET", url : "** / users", ответ: [{name: "Valentino Gagliardi"}]}); cy.visit ("/"); cy.contains ("Valentino Gagliardi");});});

Обратите внимание, как я могу заглушить ответ с помощью cy.route . Если я снова запускаю тест, он проходит:

Если я снова запускаю тест, он проходит:

Cypress снова дает вам четкое указание в деталях теста: XHR Stub означает, что мы не взаимодействуем с реальным сервисом. Есть даже раздел «маршруты», который дает вам информацию о маршрутах, которые мы прорезали. Ухоженная!

Теперь это выглядит очень умно, но, как и в случае с насмешками, заглушение ответов не дает никаких признаков того, будет ли приложение работать в производстве. Насмешки и окурки великолепны, но я советую использовать их с осторожностью .

РЕСУРСЫ : если вы хотите узнать больше о TDD с двойной петлей, смотрите не дальше Повинуйтесь тестирующему козлу Гарри Персиваль (это для Python, но концепции одинаковы для всех языков программирования). Чтобы узнать о заглушке в Cypress, ознакомьтесь с официальным документом: Сетевые запросы , Если вы не понимаете насмешки и заглушки, проверьте В чем разница между заглушкой, макетом и виртуальным сервисом ?

Я задал этот вопрос на Reddit некоторое время назад: « Какой консенсус в сообществе React для тестирования компонентов React

Я был в процессе подготовки учебной программы, и мне было интересно, есть ли библиотека выбора для тестирования компонентов.

Шон Ван прокомментировал Reddit: «тестирование - чрезвычайно сложная и нюансированная тема, по которой в JS нет единого мнения, а тем более в React».

Я не пытался найти лучшую библиотеку для тестирования React. Главным образом потому, что нет ни одного.

Но есть одна истина, как мы видели в предыдущих разделах: всегда проверяйте ожидаемое поведение ваших компонентов. Не проверяйте внутреннюю реализацию, даже если Enzyme или реагировать на тестирование делают это легко .

Говоря о библиотеках, я стараюсь использовать Enzyme (и поверхностный рендеринг) как можно меньше. И вам следует избегать поверхностного рендеринга. Кент С. Доддс дает тот же совет в Почему я никогда не использую неглубокий рендеринг ,

(Кент создал хорошую библиотеку для тестирования React: реагировать тестирование библиотека , Я предлагаю вам взглянуть!).

В конце я решил сосредоточить это руководство в основном на рендерере-тест-рендерере, потому что это низко висящий плод для тестирования компонентов React. Плюс на 100% поддерживается командой React.

Это живое, живое руководство по тестированию в React. Постоянно обновляется, лучше вы в закладки!

Я Валентино Гальярди, и я помогаю занятым людям освоить этот безумный современный JavaScript-материал. Я занимаюсь обучением и консультированием по JavaScript, React, Redux.

Давайте свяжемся!

Тестовый пакет?
Вам знакома эта история?
Почему мы должны тестировать наши приложения с первого взгляда?
Ты согласен с этим?
Доверяете ли вы непроверенному коду от других разработчиков?
Но что происходит, когда вы модифицируете компонент?
Как бы вы пошли об этом?
Почему так?
Даже если это плохая практика, как я могу проверить внутренние методы на моих компонентах React?
Есть ли способ проверить это?