Как подменять данные в SSR-сайтах

Привет, на связи Surf Web Team и Никита, QA Surf!  

Бывает, что для тестирования не хватает тестовых данных: не настроены параметры в админ-панели, бэкенд не присылает конкретные поля, и мы не можем проверить поведение веб-приложения при определенном состоянии одного поля. Но не обязательно бежать к разработчикам или контент-менеджерам. Быстрее — обратиться к инструментам сниффинга трафика (например, Charles Proxy) и подменам данных. Но они работают не всегда.

Так что давайте разберемся, какие проблемы возникают при тестировании SSR-сайтов с помощью подмены данных и как сделать так, чтобы все заработало.  

Старый добрый SPA

Какие бывают типы сайтов, и как в них взаимодействуют клиент и сервер? Самый распространенный вид веб-приложений — SPA. Фронт и бэк в них взаимодействуют через API без «посредников». 

Архитектура API — SPA

Архитектура API — SPA

В таких сайтах принцип подмены данных привычен для тех, кто знаком с инструментами сниффинга. Алгоритм работы такой:

  1. Выполняем действия на стороне клиента (к примеру, кликаем на кнопку).

  2. Происходит запрос к API (например, GET /example).

  3. Бэкенд формирует данные в виде JSON и передает их Фронтенду.

  4. С помощью сниффера перехватываем ответ на запрос и подменяем нужные параметры (к примеру, title в полученном объекте).

  5. На фронтенд передается измененный JSON, и по нему отрисовывается страница.

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

Знакомство с SSR и Next.js

Менее распространенный тип сайтов — SSR. Он отличается от SPA: в SSR-сайтах клиент получает не JSON, по которому отрисовывается страница, а уже готовую страницу. 

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

Архитектура API — SSR

Архитектура API — SSR

В этом случае при взаимодействии клиента и сервера появляется «посредник» — промежуточный сервер. Здесь — это фреймворк Next.js. Его настраивают фронтенд-разработчики. «Общение» разворачивается так:  

  1. Выполняем действия на стороне клиента (к примеру, кликаем на кнопку).

  2. Происходит запрос к серверу Next.js в виде URL.

  3. Сервер Next.js принимает запрос и определяет, каким компонентом маршрута API должен обрабатываться этот URL.

  4. Next.js делает запрос к API.

  5. Бэкенд формирует данные в виде Json и передает их в Next.js.

  6. Next.js отдает полученный ответ на отрисовку HTML-страницы и генерацию JS-файлов.

  7. Готовый контент передается на клиент.

Какие проблемы могут возникнуть при тестировании SRR-сайтов

1. Инструменты сниффинга трафика не сработают, поскольку взаимодействие с API происходит «под капотом», а ответом на запрос будет HTML-файл.

2. Даже если мы подменим HTML, мы проведем эту операцию не над данными от сервера, а над версткой. Так тестирование будет некорректным. Получится, что мы самостоятельно отрисуем нужный компонент, но не проверим реакцию фронтенда на данные от бэкенда.

Как решим эти проблемы

При подмене в SPA-сайтах данные подменяются на этапе получения Json от сервера, но до его передачи в следующую инстанцию. 

В SSR и Next.js подмена происходит во время получения Next.js Json от бэкенда, но до передачи его на отрисовку и генерации JS-файлов. Поскольку всё это выполняется «под капотом», сделать подмену нужно в коде. Тогда это будет операция над данными, а значит, тестирование станет более корректным и качественным.

Архитектуру каждого проекта нужно рассматривать отдельно. Для примера возьмем проект SSR-сайта. Здесь передан основной принцип:

  1. Смотрим на нужный метод API в документации проекта (к примеру, GET /product).

  2. Ищем файл, в котором выполнится запрос этого метода.

08827f9ed24285f294743ffe70ff7416.png

  1. В блоке функции составляем маршрут к нужному параметру и прописываем подмену. Важно сделать это до блока кода с функциями dispatch, потому что там полученные данные уже передаются на отрисовку HTML и генерацию JS-файлов.

// Метод, который осуществляет запрос к API
export const getProduct =
    (article: ProductOfferDetail['article']): TAppThunk =>
    async (dispatch, _, { productCardService }) => {
        const data = await dispatch(
            requestAction({
                requestCb: (token) => productCardService.getProduct(token, article),
                type: actionSetCurrentProduct.type,
            }),
        );


        data.product.title = 'Тест' // Здесь прописана подмена
        console.log({data}) // Также можно логировать Json,  который приходит в Next.js


        // Блок кода, в котором измененный JSON выше отрисовывается на странице
        dispatch(actionSetCurrentProduct(data));
        dispatch(actionSetProductDeliveryInfo(data.product?.pickups));
        dispatch(actionSetBreadCrumbsList(makeProductCrumbsList(data.breadcrumbs || [])));
        dispatch(actionSetReviewProductRate(data.product?.rating || 0));
        dispatch(actionSetAllReviewsCount(data.product?.allreviews || 0));
        dispatch(actionSetReviewsList(data.topreviews || []));


        return data;
    };
  1. Локально запускаем стенд или, если стенд уже запущен, сохраняем обновленный файл. 

Вот так с помощью подмены данных можно эффективно протестировать веб-приложение со сложной архитектурой в SSR-сайтах. 

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

Больше полезного про веб-разработку — в Telegram-канале Surf Web Team. 

Кейсы, лучшие практики, новости и вакансии в команду Web Surf в одном месте. Присоединяйтесь!

© Habrahabr.ru