Тестирование API с аутентификацией и авторизацией пользователей с поддержкой Auth0

Тестирование API с аутентификацией и авторизацией пользователей с поддержкой Auth0
Тестирование API с аутентификацией и авторизацией пользователей с поддержкой Auth0 - nci @ Unsplash

У меня есть REST API и приложение SPA, при этом сервер Auth0 выдает токены доступа и позволяет конечным пользователям входить в систему с помощью своего поставщика социальных удостоверений. API ожидает получить токен доступа JWT с внешним идентификатором пользователя в утверждении sub с каждым запросом. После того, как пользователь регистрируется в первый раз (и предоставляет некоторые дополнительные сведения), локальная запись пользователя сохраняется в базе данных приложения вместе с его внешним идентификатором. Для каждого последующего запроса соответствующий домен User восстанавливается из базы данных на основе внешней идентичности, полученной в токене, и следует остальная бизнес-логика.

Как правильно протестировать конечные точки API? Auth0 предоставляет маркер для использования M2M, но этот маркер не привязан ни к одной из локальных записей пользователей в базе данных приложения. Имитация службы, которая восстанавливает домен User с использованием полученного внешнего идентификатора для возврата пользователя, предназначенного в качестве инициатора тестируемого действия, кажется громоздкой. Более того, если контроллеры очень тонкие и используют сервисный уровень напрямую для вызова бизнес-логики, что может быть недостатком, если вообще не тестировать их, а тестировать только сервисный уровень ниже?

Вопрос, который вы должны задать себе: что именно вы хотите протестировать?

Большинство, но очень простых систем имеют несколько типов тестов, и каждый из типов имеет свою цель.

Например, если ваш API содержит какую-то сложную логику, вам потребуется набор модульных тестов, которые проверяют именно эту логику, изолированно. Эти тесты выполняются в своем собственном контексте и напрямую вызывают части вашего кода. Другими словами, им не нужен API для запуска, и им даже не нужно знать, что вы пишете API.

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

Теперь и модульные тесты, и интеграционные тесты не будут обнаруживать регрессии в том, как на самом деле используется API. Скажем, в какой-то момент данный вызов зависел от наличия HTTP-заголовка Hello-World, а позже вы решили добавить к заголовку префикс X-. Откуда вы знаете, что клиенты все еще работают?

Что ж, чтобы снизить риск поломки клиентов, вы выполняете системный тест, который использует реальную клиентскую библиотеку, которая вызывает ваш реальный API. Эти тесты будут медленными (по сравнению с модульными тестами менее миллисекунды), поэтому у вас будет меньше таких тестов — скажем, несколько тысяч модульных тестов, несколько сотен интеграционных тестов и несколько десятков системных тестов. Но они все равно поймают ошибки, которые не поймают два других типа.

Следует ли использовать аутентификацию в этих системных тестах? Это зависит. Если это просто и быстро, сделайте это. Если это медленно, не делайте этого. Если вы этого не сделаете, существует несколько подходов к «обходу» аутентификации. Вы можете запустить свой API в специальном режиме с поддельной аутентификацией, основанной, например, на файлах cookie или HTTP-заголовках в запросе, где идентификатор пользователя отправляется в виде простого текста, и пароль или секрет не требуются.

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


LetsCodeIt, 19 декабря 2022 г., 00:46

Похожие посты

Как часто следует запрашивать токен при взаимодействии со сторонним API?Как правильно спроектировать систему предварительной выборки APIДолжен ли я проводить модульное тестирование внутренних функций, используемых в API, который я экспортирую?За и против использования веб-интерфейсного приложения между клиентом и Entity FrameworkАрхитектура веб-сервера и уровни веб-API: Spring Boot и Node.jsАвтоматизированное тестирование: проверить, была ли вызвана подфункция, или проверить ее результат?В чем смысл многократного выполнения одного и того же теста?Откройте важностьтестирования почтовых уведомленийв отношении функциональности почтовыхуведомлений от начала до концаЭкспорт мок-версий функций: лучшая практика или анти-паттерн? Влияние на библиотеку и тестыИспользование баз данных в памяти для модульного тестирования в ASP.NET Core и EF Core