Ведь это экономит время. Это очевидно, потому что прогнать автотест займет считанные секунды, а то и доли секунд, а вручную — десятки секунд, а то и несколько минут. Автотест автоматически сгенерит нам документацию и отчётность.  Затем автотест позволит нам снизить влияние человеческого фактора. Где автотест, который правильно настроен, всегда пройдёт без ошибок, человек может ошибиться.  Высокий уровень точности, само собой, по сравнению с ручным тестированием. Получается, автотесты — панацея, которую надо внедрять добровольно-принудительно? Это далеко не так. Случай №1 — на стадиях ранней разработки.  Когда мы только-только получили ещё сырую API и она продолжает развиваться в процессе, лучше её тестировать вручную, пока она не обретёт какую-то стабильную версию.  Есть, конечно же, исключения. Бывают случаи, когда документация уже написана и, в принципе, API дальше меняться не будет. Тогда, конечно, можно начать писать автотесты параллельно с работой разработчика, который пишет эту API. Но, мне кажется, что такие ситуации всё-таки редки.  Случай №2 — тесты, которые невозможно полностью автоматизировать. Например, когда часть теста прогоняется вручную, а часть теста автоматизирована. Это нам не даёт никакой экономии времени, по большому счёту. Тесты становится сложнее поддерживать. И их достоверность под большим вопросом. №1. Они позволяют нам упростить локализацию бага. Когда мы тестируем через UI, нам надо сначала локализовать баг, понять, где он вообще находится. Когда мы тестируем через API, мы уже понимаем, где он находится.  №2. Снижение стоимости обнаружения бага достигается благодаря тому, что мы тестируем на уровне API, а не на уровне UI.  №3. И проверка на соответствие требованиям с точки зрения надёжности, безопасности и производительности. №1. Для начала убедимся, что API смотрит на нужный стенд и базу данных. Какой смысл в неактуальных данных? Пускай даже тест прошёл, но он смотрит не туда.  №2. Затем проверяем корректность входа состояния HTTP.  №3. Проверяем полезную нагрузку ответа. Здесь нам надо проверить правильность тела JSON: имена, типы и значение полей ответа. №4. Проверяем заголовки ответа. Они влияют как на безопасность, так и на производительность.  №5. И проверяем базовую работоспособность. Если операция была завершена успешно, но заняла слишком много времени, то тест не пройден. Какие ошибки мы можем допустить, если не выполним все эти проверки?  Неактуальные результаты тестирования. Когда мы смотрим, например, не на ту базу данных или не на тот стенд, мы получаем неактуальную информацию. Пропуск багов, в том числе критичных. Несоответствие требованиям безопасности и производительности. Пользователь может оказаться беззащитным перед злоумышленником, чего нам, конечно же, не надо. Пользователь может просто не дождаться, когда выполнится целевое действие или вовсе не сможет его выполнить. Основные позитивные тесты — это прохождение успешного сценария по умолчанию. Расширенное позитивное тестирование, где мы добавляем дополнительные параметры. И негативное тестирование. Здесь мы проверяем как валидные входные данные, так и недопустимые. Также мне бы хотелось отметить, что всегда стоит уточнять. Коллеги с небольшим количеством опыта и те, кто только планирует начать работать в тестировании, обращаюсь к вам. Если что-то непонятно до конца — лучше лишний раз уточнить. Коллег с большим количеством опыта, прошу, пожалуйста, отвечайте на эти вопросы. Раз уж мы поговорили о том, что мы получаем в ответах, давайте вспомним и коды состояния HTTP.  1хх — Informational. Сотые информационные коды нам говорят, что запрос получен и обработка продолжается. 2хх — Success. Двухсотые коды состояния говорят о том, что запрос был получен, успешно обработан и понят.  3хх — Redirection. Трехсотые коды ответов говорят о том, что для выполнения запроса требуются ещё действия.  4хх — Client Error: запросы имеют плохой синтаксис или не могут быть выполнены. 5хх — сервер не в состоянии выполнить недопустимый запрос. Раз уж пойдёт речь о тестирование именно REST API, давайте же вспомним: что такое REST.  REST или Representational State Transfer — это архитектурный стиль, который описывает взаимодействие компонентов распределённого приложения внутри сети. Другими словами, это такой набор ограничений, которые дают нам возможность в дальнейшем масштабировать приложение.  RESTfull — это соответствие веб-службы требованиям REST. Вот мы уже плавно подошли к самой сути статьи, поэтому выделим… Given — позволяет узнать, что было передано в запросе. When — с каким методом и на какой эндпойнт отправляем запрос. Then — как проверяется пришедший ответ. Body — тело, в нашем случае, ответа. REST-assured вообще представляет из себя инструмент для тестирования API, и он встраивается в тесты на Java. И здесь конкретный пример, точнее схема, как оно выглядит.  Также стоит использовать паттерн Builder.  Зачем? Он позволяет сделать код понятнее, добавив подсказку того, что можно сконфигурировать, используя этот самый паттерн. Пример паттерна. Если обратить внимание, то заметим, что REST-assured соответствуют паттерну Builder.  Что нам потребуется для подготовки?  В данном случае, у нас будет тестироваться API, которая принимает параметры поиска офисов и выдаёт в результате список информации про каждый офис.  Будем использовать следующий стек: ЯП Java, библиотека REST-assured и jUnit5, и паттерн Builder.  К примеру, в нашем случае особенность заключается в том, что мы не знаем, что происходит под капотом, поскольку мы обращаемся в закрытый сервис. Нам приходится довольствоваться только ответом, который он нам возвращается.  Можно было бы порт прописывать напрямую в URL. Но вместо захардкоженного порта был написан метод, который ходит в оркестратор и получает актуальный порт и инстанс. Давайте посмотрим на неё. Это фрагмент схемы, который используется для тестирования данного проекта и данной API. Желательно, конечно, писать схему самому, но можно воспользоваться и свободными инструментами в интернете. После этого обязательно проверить и исправить сгенерированную схему.  Она проверяет тип данных. В зависимости от типа данных может применить дополнительные правила. Например, для типа данных Integer можно проверить минимальное-максимальное число, для массива Array — максимальное количество элементов, обязательность элементов (required) и так далее.  А вот пример схемы сложнее, подробнее и информативнее. Примечание: JSON-schema используется, потому что гораздо проще проверять по ней, чем каждый отдельный параметр. API отдаёт нам информацию в большом объёме, почему бы не использовать JSON-schema, в которой мы можем прописать абсолютно всё? Здесь мы задаём requestSpecification, который представляет из себя преднастройку для запросов. Он будет применяться для всех тестов, которые будут наследоваться от данного класса. Мы в нём передаём URI, путь, методы, к примеру, accept — он у нас будет проверять тип данных. Здесь же мы видим применение уже знакомых нам given, then и body.  В базовую проверку добавлена проверка на время отклика (1500 мс), что не заменяет в полной мере нагрузочное тестирование, но даёт возможность обнаружить проблему с производительностью на более раннем этапе тестирования.  Тест. А для проверки ответа описаны объекты: Дальше… Позитивные кейсы помечены тегом positive.  Позитивные проверки: Здесь мы используем функцию .assertThat — она выполняет сравнение. И видим уже знакомый нам паттерн builder. Обратите внимание, вот он паттерн: И автотест соответствует паттерну builder.  Добавляем негативные кейсы. Помечаем их тегом «negative». Не забываем, что надо писать тесты и на валидные, и на недопустимые данные.  Позже на данном проекте мы вынесли параметры в эндпойнты и добавили проверки для остальных полей запроса. В дальнейшем мы добавим тесты на проверку значений по схеме. Для чего с помощью того же паттерна builder будем подставлять значение в схему.  Если у кого-то будут предложения о том, что можно сделать ещё, напишите в комментариях, с удовольствием изучу. Конечно же, нигде не обходится без ошибок.  Ошибки, в первую очередь, которые я допускал, это такие ошибки новичка — незнание того, о чём я вам сейчас рассказываю.  Я начал автоматизировать, когда API был сырым и много менялся. Одну JSON-схему я переписывал минимум три раза. Про то, сколько раз приходилось менять код, нечего говорить. И также хочется отметить, что для каждого теста следует подбирать подходящий метод, а не городить кучу кода. Пока это абстрактные слова, но сейчас я вам объясню на конкретном примере.  Обычно мы проверяем равен ли один объект другому, используя equals.  Такая проверка не будет работать, если был сгенерирован новый идентификатор для нового объекта. Следовательно, объекты разделяются по полям идентификатора. К счастью, можно указать методу /assertThat игнорировать определённые поля, во время проверки равенства, и нам не нужно будет грузить всю вот эту кучу кода (а полей может быть ещё больше). А можно использовать… Правда, удобнее? Мы игнорируем ID и количество кода сокращается, поддерживать его становится намного проще и приятнее. Конечно же, на начальном этапе автоматизации тестов это не столь очевидно ввиду незнания синтаксиса. Достоинств много.  Быстрое получение обратной связи. Аккуратное тщательное тестирование. Высокое покрытие тестами. Быстрое обнаружение ошибок. Повторное использование тестов. Более короткие сроки поставки. Экономия времени и денег.  Но у всего есть, конечно же, своя цена. Цена внедрения автотестов API — это затраты времени на обучение. Например, я погружался в тестирование REST API с полного нуля. Обучение заняло у меня один месяц.  Проектирование же, с вопросами более опытным коллегам, заняло у меня одну неделю.  Создание автотестов на данный момент — 2 недели, но оно продолжается и сейчас, и будет продолжаться, я думаю, ещё долго.  Актуализация автотестов будет длиться до самого конца, пока используется это API. У меня было примерное понимание, что такое REST, но как автоматизировать проверки — никакого понимания у меня не было. Конечно же, я не могу сказать, что теперь я знаю о нём всё. Но, по крайней мере, могу писать тесты и как-то развиваться дальше.  Давайте же подводить итоги. Подготовка — на что следует обратить внимание, когда мы готовимся внедрять автотесты на REST API. Для начала, оцените необходимость внедрения API: нужно оно вообще вам или нет.  Затем изучите тестируемое API, так как нельзя тестировать то, чего ты не понимаешь.  Следует учесть особенности вашего кейса. Подготовить окружение. И можно переходить к основным действиям. Основные действия. Для начала составьте JSON-schema. Затем напишите тесты: на базовую проверку; на расширенные позитивные кейсы; и на негативные тесты, как с валидными, так и с невалидными данными, используя для этого паттерн builder, библиотеку REST-assured и jUnit5. В тестах: Обратите внимание на то, что API смотрит на нужный стенд и базу данных. Проверьте корректность кода состояния HTTP. Проверьте полезную нагрузку ответа. Проверьте заголовки ответа. Проверьте базовую работоспособность. Ну что ж, в принципе всё. За помощь в подготовке и корректировке кода, благодарю моих коллег QA. Была ли вам полезна статья, почерпнули ли для себя что-то новое?  Рекомендованные статьи: Как настраивать аналитику, если у вас Backend Driven UI Разбираюсь в мок-серверах и пишу свой Немного попробовали Chaos Engineering и вот что поняли Кем вы видите себя через 6 лет в тестировании? Как мы играли в тесты на Groovy и проиграли Как оптимизировать процесс привлечения клиентов B2B с помощью методов Продвинутой Аналитики Подборка книг по QA без Романа Савина Про микросервисы на примерах Настолки, расследования, охота на уток: как делать активности, которые запоминаются Как перестать волноваться и полюбить хакатоны Также подписывайтесь на Телеграм-канал Alfa Digital — там мы постим новости, опросы, видео с митапов, краткие выжимки из статей, иногда шутим.