Найти тему

Как я учился тестировать React. Часть 2.

Оглавление

Всем доброго дня. В предыдущий статье мы определили самые главные документы по тестированию rect приложения. Сегодня будет первый практический пример.

Давайте ответим на вопрос, что нужно для написания теста? Наверно много чего 🙃.

Давайте хотя бы для начала создадим файл в котором будем писать код.

Сразу вопросы. А как его назвать? Где сохранить?

И тут нам придет на помощь первый документ из части 1 - "документация по Create React App". В разделе "Running Tests" сказано:

Jest будет искать тестовые файлы с любым из следующих популярных соглашений об именовании:
Файлы с .js суффиксом в __tests__ папках.
Файлы с .test.js суффиксом.
Файлы с .spec.js суффиксом.
.test.js / .spec.js Файлы (или __tests__ папки) могут располагаться на любой глубине под src папкой верхнего уровня.
Мы рекомендуем размещать тестовые файлы (или __tests__ папки) рядом с тестируемым кодом, чтобы относительный импорт выглядел короче. Например, если App.test.js и App.js находятся в одной папке, тесту требуется только import App from './App' вместо длинного относительного пути. Коллокация также помогает быстрее находить тесты в более крупных проектах.

Исчерпывающе не правда ли?

Подопытное приложение у меня маленькое, поэтому я создам папку __tests__ прямо в корне проекта (внутри папки src). Создам файл render.test.tsx в котором мы напишем первый тест, который будет проверять что наше todo приложение правильно отображается при первой загрузке. Вот моя структура проекта:

Замечу, что если вы в своем тесте тестируете компоненты react написанные на typescript то расширение файла с тестами должно быть именно tsx.

Дальше предлагая разобраться с тем, что и для чего необходимо импортировать в файл с тестом.

-2

1. Наверно сначала нужно импортировать компонент который будем тестировать. А куда ж без него 🙃. Строчка 2.

2. Если есть react компонент значит нужен реакт. Импортируем и его. Строчка 1.

3. Далее нужно импортировать какие то инструменты тестирования. Как нам намекают здесь нужно импортировать функцию рендеринга (render) и объект screen.

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

Если ваш проект создан утилитой create react app, то в терминале vs code введите команду "npm run test" и чудо случится!

-3

И с ходу получаем ошибку в строчке 8. Давайте разбираться.

Ошибка в строчке 8 говорит, что "Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>Jest". Без перевода можно догадаться что jest ругается на то, что мы рендерим компонент без react-redux context. Совсем забыл вам сказать, что использую Redux в своём приложении 🙂. Для того что бы тестировать приложение построенное с использованием Redux, необходимо создать stor и тестируемый компонент обернуть в Provider. Давайте так и поступим.

Вернёмся к вопросу импорта и добавим в тест всё что нужно для создания stor.

-4

Далее создадим тот самый stor в строчках 13-16

-5

Далее в строчках 18-22 создадим JSX.Element который представляет собой наш тестируемый компонент обёрнутый в Provider редакса. В строке 24 скажем jest отрендерить наш компонент. И снова радостно получаем ошибку в строке 28 которая гласит "TypeError: expect(...).toBeInTheDocument is not a functionJest". Дело в том, что jest ничего не знает о методе toBeInTheDocument(). Потому, что этот метод принадлежит к библиотеке jest-dom, которая предоставляет пользовательские средства сопоставления элементов DOM для Jest и её нужно установить дополнительно и импортировать в наш тест в 5-й строке ниже.

-6

Вуаля! Вот весь наш тест целые 32 строчки. И всё работает 🤩🤩👏.

Теперь давайте по подробнее про то что происходит в строчках 27-29.

Функция expect используется каждый раз, когда вы хотите проверить значение. Аргументом функции является либо значение либо код который значение возвращает. В нашем случае код screen.getByRole("textbox", { name: "addTodoInput" }) венё некий DOM элемент, а функция toBeInTheDocument проверит находится ли этот DOM элемент в объекте document. Более подробно метод getByRole и ему подобные разберём в следующих частях.