Модульное тестирование для микро-интерфейсного приложения React

avatar
Alex
9 августа 2021 в 00:42
498
1
3

Я пытаюсь написать модульные тесты для веб-приложения React Spa, использующего архитектуру микроинтерфейса. Мой первый шаг — написать модульные тесты для контейнера приложения.

Реагирующий компонент контейнера приложения использует react-router, содержащий переключатель с последующими маршрутами для отображения компонентов в области основного содержимого.

Каждое приложение монтируется в контейнер приложения с помощью интеграции среды выполнения JavaScript.

Я использую React-Testing-Library и Jest как часть своего набора инструментов для тестирования.

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

У меня есть 3 проблемы, по которым я хотел бы получить консультацию.

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

  2. Я пытался протестировать на уровне компонента страницы, чтобы избежать проблем с аутентификацией и для простоты, но компонент содержит компонент из библиотеки React Router, и Jest жалуется, что я не должен использовать компонент <Link>, который не заключен в компонент <Router>. Однако компонент <Router> присутствует на уровне родительского компонента при выполнении во время выполнения. Как я могу сказать Jest «игнорировать» эту проблему?

    Мне не удалось найти конфигурацию, позволяющую игнорировать эту ошибку.

  3. Из-за проблемы № 2 я попытался написать модульные тесты, визуализируя компонент <App>, но этот компонент передается компоненту более высокого порядка, который выполняет проверку подлинности. Как я могу сосредоточиться на тестировании конечного результата, а не на функциональности HOC аутентификации, чтобы я мог заставить компонент отобразиться и выполнить мои тесты?

Источник
Adam
9 августа 2021 в 01:12
0

Термин микрофронтенд в вашем вопросе сбивает меня с толку. Это имеет очень конкретное значение — это на самом деле микрофронтенд приложение, или вы задаете общие вопросы о тестировании реагирующих компонентов? Приложение микрофронтенда содержит «связующий» код, а затем содержит кучу отдельных компонентов (которые могут быть написаны на различных фреймворках, даже на vanilla js).

Alex
9 августа 2021 в 01:17
0

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

Adam
9 августа 2021 в 01:19
1

Что делает его микрофронтендом? Если все приложение написано на React, а источники компонентов поступают из разных мест/репозиториев, это не микрофронтенд, это просто React-приложение. Ответ на номер 2 прост — в настройках теста вы оборачиваете Router вокруг вашего предметного компонента.

Ответы (1)

avatar
Adam
9 августа 2021 в 01:27
1

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

Например, предположим, что ваш компонент приложения выглядит так:

const App = () => (
   return (
     <Router>
       <Provider store={store}>
         <ThemeProvider>
            <Main/> <- the main entry point to your application
         </ThemeProvider>
       </Provider>
     </Router>
   );
);

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

Итак, как это сделать? Смоделируйте компонент Main в своем наборе тестов и убедитесь, что ваш макет отображается в нужном месте в иерархии. Вы также должны убедиться, что он отображает Router в Provider с правильными (вероятно, издевательскими store) и ThemeProvider. Опять же, содержимое каждого из этих компонентов не важно, важно только то, что приложение отображает их в соответствующей иерархии, поскольку это единственная логика, содержащаяся в App.

.

Как только вы начнете переходить границы и попытаетесь проверить содержимое Main в наборе тестов для App, это может очень быстро стать очень громоздким, т. е. если вы измените реализацию Main, вы в конечном итоге сломать ваши App тесты, и это просто неправильно (IMO).

То, что я описал выше, является стратегией тестирования поверхностного рендеринга. Некоторые люди протестуют против этой стратегии (даже сама библиотека react-testing-library не поддерживает ее). У меня есть немалый опыт написания и тестирования реагирующего кода, определенно выступаю за поверхностный рендеринг/насмешку над компонентами. Конечно, каждый случай уникален, и это не всегда может быть лучшей стратегией, но почти во всех обстоятельствах, с которыми я сталкивался, это позволяет вам инкапсулировать вашу логику в тестируемые фрагменты и упрощает удаление/рефакторинг.

Я попытался протестировать на уровне компонента страницы, чтобы избежать проблем с аутентификацией и для простоты, но компонент содержит компонент из библиотеки React Router, и Jest жалуется, что мне не следует использовать компонент, не заключенный в составная часть. Однако компонент присутствует на уровне родительского компонента при выполнении во время выполнения. Как я могу сказать Jest «игнорировать» эту проблему?

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

Если вашему компоненту нужен определенный контекст (например, Link нужен NavigationContext), то ваша задача — предоставить этот контекст в тестовой настройке.

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

import { render, screen } from '@testing-library/react' 
import { Router } from 'react-router-dom';
import { MySubjectComponent } from './MySubjectComponent';

it('should show my component with a Link',() => {
  // provide a Router in the test fixture because you
  // know MySubjectComponent needs it
  render(
    <Router>
      <MySubjectComponent/>
    </Router>
  );
});

Как я могу сосредоточиться на тестировании конечного результата, а не на функциональности HOC аутентификации, чтобы я мог заставить компонент отобразиться и выполнить мои тесты?

Ответ всегда один и тот же, независимо от того, что вы пытаетесь протестировать — имитируйте зависимости.

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

Чтобы протестировать HOC, вам нужно смоделировать зависимости HOC (функции, запросы и ответы, которые он использует для выполнения аутентификации) и передать фиктивный компонент, который вы можете сделать простым утверждением о свойствах, которые HOC перешел к нему.

Хорошее тестирование — это то, о чем я могу говорить неделями.