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

Прежде чем перейти к нашей основной теме, мы можем бегло просмотреть тестовые песни. Они обычно собраны под 3 заголовками. Модульный тест, интеграционный тест, сквозной тест.

1 – Модульный тест.Можно сказать, что это наименьший модуль, который мы можем протестировать в нашем приложении. Можно протестировать отдельный функциональный модуль, объект и т. д.
2 – Интеграционный тест: это тип теста, который мы применяем для проверки согласованности работы различных частей. друг с другом. Это этап тестирования программного обеспечения, на котором отдельные программные модули собираются и тестируются как группа. Мы можем думать об этом так, как будто мы проверяем, как работают эти тесты, выполняя более одного модульного теста.

Основные шаги по настройке сквозных тестов:
a-Просмотр требований, которые вы будете проверять с помощью end- завершающее тестирование.
b-Настройка тестовых сред и соблюдение требований к оборудованию/программному обеспечению.
c-Идентификация всех процессов ваших систем и интегрированных подсистемы.
d-Определение ролей и обязанностей для каждой системы

3- Сквозное тестирование.Известно как сквозное тестирование. Он применяется для проверки того, работает ли наше приложение в комплексе с комбинацией наших модульных и интеграционных тестов. Короче говоря, мы полностью тестируем наше приложение. Используйте настоящий браузер и сервер (Selenium, Cypress).

Прежде всего, о чем я хочу поговорить, так это об отношениях между Библиотекой тестирования React и Jest.

Библиотека тестирования React не является альтернативой Jest, потому что каждая из них имеет свою уникальную функцию, атрибут и задачу, а также они нужны друг другу. Jest - это средство запуска тестов, которое дает вам возможность запускать тесты с помощью Jest из командной строки. Он находит тесты - запускает тесты и определяет, пройден ли тест или нет. Его очень легко документировать и синтаксис. Это также позволяет нам легко писать тесты без каких-либо настроек конфигурации. Библиотека тестирования React — одна из библиотек тестирования для тестирования компонентов React, в отличие от Jest. Jest — это среда тестирования JavaScript. Комбинация Jest обеспечивает большую скорость итерации, поэтому вы можете иметь больше полномочий и контроля над обработчиком кода и тем, как он работает. Библиотека тестирования React — это набор утилит, позволяющих тестировать компоненты React.

Начнем

Если вы создали свой проект с помощью «React Create App», следующие отмеченные строки будут прямо в вашем приложении. Так что вам не нужно делать ничего дополнительно. Но вы создаете его сами, вам нужно их добавить.

установка npm — save-dev @testing-library/реакция

И если вы зайдете в файл «src» и посмотрите, вы увидите первый тестовый файл, созданный с помощью «react create app». Как и в соседнем примере. Мы можем легко запустить это с помощью «npm run test».

При написании теста для компонента обычно создается файл с именем «__tests__» для тестируемого компонента, а в нем создается тестовый файл «filename.test.js». То, что я хочу рассказать, показано на изображении ниже

Здесь был создан компонент счетчика, и к нему был добавлен специальный тестовый файл для написания теста.

Кроме того, не имеет значения, используете ли вы "it" или "test" при написании теста. Тебе решать.

Поскольку курсов и контента на эту тему очень много как на youtube, так и на таких платформах, как udemy, я не буду подробно рассказывать о том, как это написано, я просто попытаюсь объяснить предмет, приведя несколько небольших примеров о его общем логика.

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

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

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

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

Что касается концепции Mocking, давайте сначала посмотрим, что означает Simulation. Симуляция используется для обозначения похожего или поддельного чего-либо в нетехническом смысле. С технической точки зрения, это имитация работы реального процесса или системы во времени. Это модель системы или процесса, которая включает определенные отношения между объектами системы.

Мокирование означает создание фальшивой версии внешней или внутренней службы, которая может заменить настоящую, помогая вашим тестам работать быстрее. Поскольку он имитирует объекты, которые контролируемым образом имитируют поведение реальных объектов, они могут находиться на вашем локальном компьютере или в общедоступном Интернете. Ответы могут быть статическими или динамическими. В результате Mocking — это поддельные состояния, которые мы используем для имитации поведения реальных данных.

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

Можно игнорировать тесты, набрав it.skip(…) или describe.skip(…) внутри тестов с использованием .skip. Вы также можете выбрать, какие именно тесты вы хотите запустить, сказав it.only(…) или define.only(…).

рендеринг — это метод рендеринга заданных компонентов.

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

Запросы — это методы, которые Testing Library предоставляет вам для поиска элементов на странице. Существует несколько типов запросов (получить, найти, запросить); разница между ними заключается в том, выдаст ли запрос ошибку, если элемент не найден, или вернет обещание и повторит попытку. Можно привести и объяснить много примеров, связанных с этой темой (getByLabelText, getByTitle и т. д.), но их важные характеристики приведены в таблице ниже.

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

getBy =› Возвращает первый совпадающий узел для запроса, возвращает ошибку, если нет совпадающих элементов или найдено более одного совпадения.

getAllBy =› Возвращает массив всех совпадающих узлов для запроса и выдает ошибку, если нет совпадающих элементов.

findBy =›Возвращает обещание разрешения, когда найден элемент, соответствующий заданному запросу.

findAllBy =› Возвращает обещание, которое разрешает массив элементов, когда найден любой элемент, соответствующий запросу.

queryBy =›Полезно для подтверждения переадресации несуществующего элемента. Возвращает первый соответствующий узел для запроса и возвращает значение null, если элементы не совпадают.

Поясним это на коротком примере, например, если вы хотите «зависать» при наведении курсора на что-то на экране, вы можете использовать это. Потому что перед зависанием это будет «not.toBeInTheDocument()», и это позволит нам продолжить наш путь без получения ошибки.

А в этом примере спросите вы. Почему мы использовали «await waitForElementToBeRemoved» здесь, когда он «unhover», он будет скрыт, поэтому мы могли бы использовать «not.toBeInTheDocument()». Да, вы правы, но если мы поступим так, то получим ошибку «act(…)». Поскольку «DOM» работает быстро, он не ждет нашей операции «unhover». Вот почему «not.toBeInTheDocument()» не происходит. Нам нужно дождаться «unhover», поэтому мы использовали «not.toBeInTheDocument()».

queryAllBy =› Возвращает массив всех совпадающих узлов для запроса и возвращает пустой массив ([]), если нет совпадающих элементов.

Желающие сделать упражнения на эту тему могут поделиться здесь.

Итак, как нам проверить, сколько частей чего-то, что мы хотим видеть на экране?
Допустим, у вас есть 2 изображения на экране, и вы хотите сначала проверить, сколько их там, а затем использовать «alt», чтобы увидеть, являются ли они правильными изображениями. Вы можете сделать это следующим образом. В первую очередь вам нужно найти эти картинки на экране с помощью «screen» классическим способом, а затем вы можете проверить количество этих картинок с помощью «toHaveLength».

Во-вторых, вам очень легко проверить, являются ли отмеченные вами изображения теми, которые вам нужны, если вы добавили к изображениям alt. Если вы собираетесь использовать элемент управления более чем для одного изображения (массив объектов), вы можете сделать это с помощью "toEqual" следующим образом. Конечно, вы должны сначала "отобразить", так как для этого будет более одного изображения.

Второй вопрос, который здесь возникнет, — почему мы использовали «async-await»?

Когда вы хотите, чтобы одно и то же появилось асинхронно на странице, вы должны использовать await findBy, потому что соединения почти всегда асинхронны.

Как и выше, допустим, вы хотите брать и отображать изображения на сервере, в этом случае, поскольку вам нужна асинхронность, если процесс продолжится без получения изображений, codetest выдаст ошибку, потому что он не может принять что-то, что не там и пройти тест.

Прежде чем я закончу, есть еще одна небольшая, но полезная тема, которую я хотел бы затронуть. "test.only" и "test.skip".

Допустим, вы написали более одного теста для компонента, и ваш тест не прошел, и вам нужно найти проблему. На этом этапе они приходят к вам на помощь. Как?

Если вы напишете “.only” рядом с написанным вами тестом, будет работать только этот тест, а остальные нет, чтобы вы могли понять, есть ли ошибка в этом тесте, и вы можете его проверить. Подробнее.

Если вы наберете “.skip”, тест будет пропущен, а другие написанные вами тесты будут запущены с аналогичной логикой. Таким образом, вы можете легко увидеть, проблема в этом тесте или нет.

test.only('мой тест примерно….' () =›{})

test.skip('мой тест примерно….' () =›{})

Теперь давайте перейдем к другому важному вопросу: waitFor? Зачем и где бы вы его использовали? Поясним на примере.

Допустим, вы хотите, чтобы на экране одновременно отображались 2 предупреждающих сообщения. Как известно, между ними есть небольшая разница во времени, поэтому они не происходят одновременно, а одно из них происходит немного раньше. Если вы не используете waitFor, ваше приложение быстро возобновит работу системы при получении первого предупреждающего сообщения и продолжит свою работу, не дожидаясь второго предупреждения, а если вы наберете «expect(alerts).toHaveLength(2)» и подождите два, вас встретит ошибка.

В чем разница между Userevent и fireEvent?

Userevent – это дополнительная библиотека для библиотеки тестирования, которая обеспечивает более продвинутое моделирование взаимодействия с браузером, чем встроенный метод fireEvent.

За кулисами userEvent использует fireEvent. Вы можете считать fireEvent низкоуровневым API, а userEvent устанавливает поток действий.

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

Пользовательское событие, с другой стороны, отправляет события так, как если бы пользователь взаимодействовал с документом. Это может привести к тем же событиям, которые вы ранее отправляли напрямую для каждого события fireEvent, но также может выявить ошибки, из-за которых пользователь не сможет инициировать указанные события.

Хороший пример: когда вы запускаете событие щелчка по кнопке с помощью fireEvent.click, кнопка не будет сфокусирована. Кнопка не сфокусирована. Но с помощью userEvent.click() эта кнопка будет сфокусирована. useEvent может лучше отражать реальное поведение пользователей.

Удобные методы запуска событий DOM

Еще одна важная проблема, которую необходимо упомянуть, — это концепция fireevent. Это удобные методы запуска событий DOM. Короче говоря, это запускает события DOM, такие как sclick , фокус и т. д. Чтобы узнать больше об этих типах событий, вы можете проверить здесь.

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

Ресурсы:

https://jestjs.io/

https://testing-library.com/

https://www.w3.org/TR/wai-aria/#role_definitions

https://gabrieltanner.org/blog/testing-introduction/

https://thomlom.dev/how-to-test-javascript-with-jest/

https://thomlom.dev/beginner-guide-testing-react-apps/