Есть масса причин, по которым вы должны тестировать свой код. Вы услышите все, от «повышения уверенности» до «установления высоких стандартов». Для меня тесты в большинстве случаев являются моей страховкой, чтобы убедиться, что я случайно не сломаю что-то с будущим изменением кода. Когда кодовая база небольшая, не так уж сложно держать в голове побочные эффекты и знать, когда изменение в модуле А приведет к взрыву чего-то в модуле Б. Но кодовые базы имеют тенденцию не оставаться маленькими. И модули, как правило, работают в течение длительного периода времени без необходимости прикасаться к ним. Так что сэкономьте время и напишите более качественные тесты!

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

Хорошо Тесты

Итак, если вы только начинаете, у Jest есть функция, позволяющая очень легко начать работу. Тесты снимков:

Бум! У вас есть тест, который предупредит вас, если разметка в вашем компоненте вообще изменится. Проблема с такими тестами моментальных снимков:

  • Они не очень хороши в том, чтобы убедиться, что ваш компонент работает должным образом, только в том, что он отображает HTML.
  • Большинство рецензентов не будут глубоко изучать файл моментального снимка. Они будут считать, что вы знаете, что делаете, и просто пропустят это.
  • Гораздо проще сломать снэпшот-тест, а потом просто обновить его, добавив -u при запуске jest, особо не задумываясь о последствиях.

Таким образом, снэпшот-тест даст вам некоторые базовые гарантии. Но в долгосрочной перспективе это действительно мало что вам даст.

Лучшие тесты

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

Итак, краткое прохождение этих тестов:

  • Shallow render нашего компонента с функцией шутливого макета.
  • Найдите компонент кнопки и вызовите его свойство onClick.
  • Убедитесь, что наша фиктивная функция была вызвана.

Тест №2:

  • Неглубокий рендеринг нашего компонента снова.
  • Вручную установить состояние нашего компонента
  • Убедитесь, что он передает значение дочернему компоненту, как и ожидалось.

Некоторые люди скажут, что это очень хороший тест. Его область действия ограничена нашим компонентом. Он проверяет границы нашего компонента. Это выглядит хорошо. Проблема этого теста в том, что он сильно зависит от деталей реализации. Для этого требуется, чтобы у вас было значение состояния aValue, поэтому рефакторинг его в Redux или иным образом сделает этот тест довольно хрупким. Этот тест также не гарантирует, что он правильно взаимодействует со своим дочерним компонентом. (Например, этот тест проверяет, что наш компонент Button имеет onClick, но если свойство Button на самом деле onSelect, ваш тест пройдет, но код будет сломан). 😿

Больше лучших тестов

Некоторые еще более лучшие тесты могут выглядеть так:

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

Этот тест не идеален. Мы должны делать предположения о дочерних компонентах (что текстовое поле с атрибутом test-id text существует и т. д.). Но, имхо, это нормально. По моему опыту, при написании тестов с помощью React вы в основном пишете интеграционные тесты вниз по дереву и выполняете некоторые граничные тесты вверх по дереву.

Что это обозначает?

Когда вы создали свой компонент React, вы создали жесткую зависимость от этого компонента ко всем его дочерним компонентам. Итак, вы должны писать тесты, которые гарантируют, что эта зависимость сохраняется и действительна. Вы делаете это, взаимодействуя с этими дочерними компонентами в своем тесте. Затем вы должны убедиться, что эти компоненты изменяют ваш компонент так, как вы ожидаете.

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

На самом деле вы должны сделать все возможное, чтобы убедиться, что рабочий процесс пользователя работает так, как вы ожидаете. HTML может измениться, но пока ваши компоненты все еще могут взаимодействовать, как вы ожидаете, вы можете оставить эти изменения HTML для визуального тестирования (это совсем другая статья: D)

В заключении

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