Руководство по использованию Cypress для перехвата API в UI-автоматизации |
27.01.2025 00:00 | |
Автор: Сватика Визань (Swathika Visagn) Инженеры-автоматизаторы согласятся со мной: устойчивый фреймворк автоматизации – это солидный фундамент для проверки здоровья приложения. Задача добиться устойчивости, внедряя лучшие практики взаимодействия тестов с приложением – это и ответственность автоматизаторов, и их награда. Одна из таких практик – это «перехватывать» API, что добавит очков зрелости тест-стратегии и фреймворку. Перехват означает взятие контроля над API путем подслушивания запросов и манипулирования ими через изменение свойств запроса или ответа. Я считаю, что это очень мощный инструмент автоматизаторов, помогающий создавать устойчивые тесты пограничных случаев. В этой статье мы разберемся, что такое перехват API, и как успешно им воспользоваться, тестируя пользовательский интерфейс при помощи Cypress. Что такое перехват API? Термин «перехват» означает остановку и/или изменение чего-то до того, как оно достигнет цели. В тест-автоматизации перехват API означает захват собирающегося выстрелить API и манипуляцию его свойствами. Затем можно заглушить запрос, пока он не дошел до сервера, и схожим образом изменить свойства ответа, возвращенные сервером, до того, как они достигнут интерфейса. Это позволяет гибко манипулировать поведением интерфейса для проверки граничных случаев. Возможность перехвата API дают многие инструменты – из них наиболее популярны Cypress, Playwright и Postman. Основная идеяНельзя однозначно сказать, какой инструмент будет наилучшим, потому что это напрямую зависит от природы приложения и нужд проекта. С моей точки зрения, у каждого инструмента есть свои сильные стороны, и на каждый из них большой спрос у тестировщиков. К примеру, Postman предназначен именно для создания и тестирования API, у него дружелюбный к новичкам графический интерфейс, и одна из его возможностей – это создавать заглушки и имитаторы для API до его интеграции с другими службами. Это позволяет разработке и тестированию внедрять гибкие принципы, тестируя API изолированно. Cypress запускает свои тесты в браузере, что дает пользователям возможность тестировать на всех уровнях тест-пирамиды. Cypress позволяет взаимодействовать с API через фронтэнд-тесты интерфейса, и в этой статье мы будем говорить именно об этом. Сшивание и перехватСшивание и перехват – два разных термина. Когда мы используем перехват API внутри UI-тестов, это называется «сшиванием». Мы подробно обсудили перехват, разберемся со сшиванием. Если вдаваться в подробности, шов в швейном деле – это линия, по которой сшиваются два куска ткани. Сшивание в тест-автоматизации – это процесс соединения разных уровней тест-пирамиды. Энджи Джонс прекрасно объяснила это, как размывание границ тест-автоматизации, и продемонстрировала реальные примеры в своей статье. Ниже я продемонстрирую, как внедрить сшивание – то есть перехват API внутри UI-тестов – на реальном демо-приложении от Cypress. Настройка и запуск демо-приложенияДля начала настройки приложения клонируйте RWA из официального GitHub-репозитория Cypress. Советую следовать пошаговым инструкциям на сайте Cypress до начала клонирования. Подсвечу самое важное:
Клонировав и запустив приложение, вы сможете успешно авторизоваться, используя список тестовых пользователей и паролей, предоставленный в разделе репозитория Getting Started. Если столкнетесь с проблемами, убедитесь, что ваша версия node совместима с приложением. Другие проблемы можно легко обсудить и решить при помощи сообщества Cypress. Я запустил приложение, и появилась страница авторизации банка: Изображение 1: Экран авторизации демо-приложения Cypress Успешно авторизовавшись, вы попадете на домашнюю страницу: Изображение 2: Домашняя страница демо-приложения Cypress Настройка фреймворка CypressЗапустив приложение, нужно построить фреймворк Cypress, чтобы создавать тесты. Для упрощения процесса рекомендую начать новый проект node.js, установив package.json и cypress. Так как эти шаги выходят за рамки статьи, предположу, что читатели знакомы с настройкой фреймворка Cypress с нуля – это довольно логичный процесс всего из трех команд. Откройте новую директорию,
Взгляните сюда для настройки Cypress. Обзор тест-сценариевCypress дает пользователям доступ к объектам с информацией об API-запросах, и позволяет проверять их свойства. Тут детально объясняются тест-стратегии перехвата API и основы перехвата. Cypress довольно гибко работает с перехватом API – возможности можно сочетать и комбинировать в пределах одного теста, заглушая ответ или запрос и не позволяя им достичь сервера. Тест-стратегии, о которых пойдет речь в этой статье:
Разберем эти стратегии подробно по порядку следования в списке. Заглушка для тела ответаРазберем тест-сценарии для заглушки тела ответа. На вкладке личных операций для пользователя выводится ряд результатов. Перехватим API-запрос, возвращающий эти операции, и изменим тело ответа так, чтобы оно не возвращало результатов. Мне интересно, как UI справится с таким ответом, и какие изменения в нем произойдут. Изображение 3: Страницы операций демо-приложения Cypress В тестах Cypress следуйте этим шагам:
Исследуйте UI, чтобы увидеть, как API-запрос отправится при клике на вкладку ‘Mine’. Обращайте внимание на конечную точку URL, метод HTTP, наполнение (если есть), тело ответа и статус ответа. Изображение 4: Детали API-запроса личных операций У вкладки Network в инструментах разработчика есть вкладка Response, где можно видеть, что у тела есть свойство «результаты», содержащее все операции. Наша задача – заглушить ответ пустыми результатами. Изображение 5: Детали API-запроса личных операций Как можно видеть в тесте ниже, метод перехвата должен размещаться до конкретного действия пользователя (клика по вкладке Mine). Это позволит Cypress шпионить и прислушиваться к API-вызову. Как только по вкладке кликнули, Cypress заглушит результаты, заменив тело ответа с картинки выше на пустой объект. Я заглушаю ответ пустым телом JSON, синтаксис можно посмотреть в официальной документации Cypress. Когда выполнится тест ниже, вы увидите интерфейс с заглушенным ответом. Для валидации я проверяю, что локатор элемента UI для транзакций не существует. describe("validate UI for no results in user transactions", () => { В Cypress runner на изображении ниже Cypress показывает перехваченный вызов API, используя алиас, ‘personalTransactions’. Из-за заглушки ответа в интерфейсе отсутствуют личные транзакции. Теперь я проверил, что локаторы для элементов транзакции не существуют на странице. Изображение 6: Тест перехвата API личных транзакций Ожидание запроса и проверка свойств ответа (кода статуса)Иконка Notifications на домашней странице отображает все уведомления пользователя. В этом сценарии мы проверим, что код статуса ответа – 200. В тестах Cypress следуйте шагам ниже:
Исследуем UI, чтобы заглянуть в детали API. Конечная точка URL - /notifications, HTTP-метод – GET, а код статуса ответа для этого вызова должен быть 200. Изображение 7: Детали API-запроса страницы уведомлений Я перехватил этот URL и ожидал его, используя алиас. Проверку статуса ответа связана с возвращенным объектом. Синтаксис можно посмотреть тут. describe("validate UI for user notifications", () => { beforeEach("login the application", () => { cy.loginApp(); }); it("should return a status code of 200", () => { cy.intercept("http://localhost:3001/notifications").as("notifications"); cy.get('[data-test="nav-top-notifications-link"]').click(); cy.wait("@notifications").its("response.statusCode").should("eq", 200); }); }); Cypress runner ниже показывает ожидание перехваченного алиаса и проверку, что код статуса ответа равен 200. Изображение 8: Тест перехвата API уведомлений Заглушка кода статуса ответаВ этом тест-сценарии мы будем использовать ту же вкладку Notifications, что и в предыдущем примере. Вместо проверки кода статуса ответа мы заглушим его, изменив на 401 (не авторизован), и проверим интерфейс для такого ответа. В тестах Cypress следуйте шагам ниже:
Синтаксис Cypress для заглушки кода статуса ответа можно посмотреть здесь. Заглушим статус ответа, заменив его на 401, и проверим, что UI-локатор для пустого списка уведомлений присутствует в DOM. describe("validate UI for user notifications", () => {
beforeEach("login the application", () => {
cy.loginApp();
});
it("should return a status code of 200", () => {
cy.intercept("http://localhost:3001/notifications").as("notifications");
cy.get('[data-test="nav-top-notifications-link"]').click();
cy.wait("@notifications").its("response.statusCode").should("eq", 200);
});
it("stub response code to 401", () => {
cy.intercept("GET", "/notifications", {
statusCode: 401,
}).as("notifications");
cy.get('[data-test="nav-top-notifications-link"]').click();
cy.wait("@notifications").its("response.statusCode").should("eq", 401);
cy.get('[data-test="empty-list-header"]').should("exist");
});
});
Cypress runner ниже демонстрирует, что код ответа заглушен, а список уведомлений пуст. Проверка присутствия UI-локатора для пустого списка прошла успешно. Изображение 9: Уведомления в UI пусты из-за заглушенного API-ответа Заглушка содержимого запросаЭто мой любимый сценарий – давайте посмотрим, о чем тут речь!
Как упоминалось выше, список тестовых пользователей можно получить при помощи команды ниже, информация находится в секции Getting Started.
В интерфейсе вводится имя Katharina_Bernier. Изображение 10: Авторизация в демо-приложении Cypress как Katharina_Bernier После клика по SIGN IN вкладка Network показывает, что в запросе содержится имя пользователя Katharina_Bernier. Я меняю это тело запроса – имя пользователя изменится на Jessyca.Kuhic, существующего тестового пользователя, предоставленного Cypress. Изображение 11: API авторизации, где указана Katharina_Bernier Синтаксис отслеживания и изменения запроса с функцией routehandler можно найти здесь. Мы будем следить за вызовом API с конечной точкой /login. Когда такой запрос отправится, мы изменим его, поменяв имя пользователя на Jessyca.Kuhic – после отправки запроса мы проверим, что имя пользователя обновилось. describe("validate user login", () => { Cypress runner ниже демонстрирует, что пользователь авторизован как Katharina_Bernier, а перехваченный API показывает, что имя пользователя в запросе - Jessyca.Kuhic, и проверка прошла успешно. Это означает, что после авторизации в качестве Katharina_Bernier мы успешно заглушили содержимое запроса до того, как оно достигло сервера. Примечание: в вашем проекте вы можете использовать аналогичный сценарий для заглушки содержимого невалидным пользователем, чтобы получить тело и статус ответа для неавторизованного пользователя. Изображение 12: API авторизации с заменой содержимого на Jessyca.Kuhic Мы рассмотрели ряд хороших реальных примеров заглушки запроса и ответа с использованием перехвата Cypress. Перехватывать API можно множеством других способов – попрактикуйтесь, используя официальную документацию Cypress. У Cypress замечательное сообщество, которое поможет вам с любыми техническими проблемами и сомнениями, а их репозиторий актуален и полностью функционален. Я разместил свой репозиторий с тестами, о которых мы тут говорили, на GitHub. Это поможет вам сразу запустить тесты, запустив приложение. Пожалуйста, помните, что приложение должно быть запущено до запуска тестов Cypress. Надеюсь, эта статья поможет вам внедрить сшивание в вашу тест-автоматизацию. ЗаключениеНадеюсь, что мне удалось объяснить идею перехвата API и того, как это помогает улучшить ваши тесты. Я использую перехваты API в своих тестах, чтобы проверить результат взаимодействия с UI, сохранить свойство ответа в переменной окружения для использования в параметрах запросов, и для покрытия граничных сценариев, меняя свойства ответа. Другое важное преимущество перехватов – оно помогает управляться с хрупкостью UI. К примеру, я предпочитаю ожидать алиасов перехвата, а не жестко кодировать ожидания – как объясняется в этой статье. |