Эвристики и мнемоники в тестировании: шаблоны для тестирования API

Привет! Меня зовут Тоня Тараненко, я QA Engineer в продуктовой компании pdfFiller, а также лектор в тренинг-центре подготовки IT-специалистов. В тестировании я уже более 4 лет, из которых последние два года большую часть времени занимаюсь тестированием API на проекте signNow (в том числе исследовательским), нагрузочным тестированием микросервисов, а еще активно практикую менторство QA-свитчеров (но это скорее как хобби).

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

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

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

Материал, изложенный в этой статье, выражает личное мнение автора и не является официальной публикацией pdfFiller.

Актуальность исследовательского тестирование API

Исследовательское тестирование — системный подход к поиску и идентификации проектных рисков, а также обучение и оттачивание навыков тестировщиков во время самого процесса тестирования. Речь идет об эвристиках, мнемониках и оракулах, которые основаны на многолетнем опыте, знаниях и подходах других тестировщиков. Если использовать их, можно получить важную и полезную информацию о работе продукта для стейкхолдеров.

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

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

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

У нас на проекте, как и на любом другом, регрессионные тесты — самые первые и основные кандидаты на автоматизацию. Они запускаются регулярно, каждую регрессию и в большом количестве. Автотесты помогают не только сократить время и объем тест-кейсов на регрессии, но и высвободить ресурсы для других, более высокоуровневых задач, исследовательского тестирования. Однако, несмотря на тот факт, что большинство регрессионных сьютов автоматизировано, ручное регрессионное тестирование тоже необходимо.

И даже во время проведения регрессии можно применять исследовательский подход. Хотя он больше подойдет для небольших проектов, где тест-сьюты можно заменить небольшим чек-листом с основными блоками функционала. Именно в этом случае необходима высокая квалификация и хорошее знание продукта командой тестировщиков. Еще один подход к исследовательскому тестированию — вовлечение в его процесс новичков QA-команды. Таким образом мы получим свежий взгляд на продукт: не с точки зрения проверяемого функционала, а в разрезе возможностей разных участников команды.

Тестирование с точки зрения выполнения (исследовательское тестирование). Знатоки исследовательского тестирования рассматривают его как определенную деятельность или импровизацию, направленную на улучшение и развитие навыков у тех, кто его использует. По сравнению с предыдущим подходом, этот дает нам следующие возможности:

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

Для полноценного и максимально объективного тестирования нам необходимо использовать оба подхода. Они являются отличным дополнением друг друга. Чтобы начать практиковать исследовательское тестирование API, специалисту не нужен ни пользовательский интерфейс приложения, ни наличие завершенного функционала.

13 паттернов для тестирования API

Maaret Pyhäjärvi, автор блога, описала основные шаблоны для исследовательского тестирования API в своей статье. Она является профессиональным тестировщиком ПО и разработчиком, преподает исследовательское тестирование и консультирует команды по автоматизации тестирования на высоконагруженных проектах.

Концентрация на работе с ограниченным знанием продукта. С чего вообще следует начинать исследовательское тестирование API? Прежде всего стоит использовать инструменты тестирования трафика, например Fiddler и Charles, с помощью которых можно убедиться, что сайт корректно функционирует по протоколу HTTP, запросы не содержат ошибок и структура построения логики обмена данными не имеет слабых мест.

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

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

Определение структурных элементов продукта. Если приложение рассматривать как чёрный ящик, то API — это множество «ручек», которые доступны пользователю и которые он может вертеть и дёргать. Это API calls, операции, запросы и ответы на них, входящие и исходящие данные, эксепшены и зависимости.

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

Окружение, от которого зависит API. Вряд ли ваш API существует в сферическом вакууме, очевидно, что он зависит от определенного окружения. Речь идет о специфическом синтаксисе используемого языка программирования, а также о всех тех приложениях и инструментах, которые используют ваш API.

Полезный лайфхак — небольшие зарисовки в mindmap или же создание блок-схем работы API, которые вы сможете расширять и детализировать в процессе тестирования и получения новой информации о продукте.

Хорошим примером подобной блок-схемы может быть Slack OAuth 2.0 Flow для получения access tokens пользователями:

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

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

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

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

Образ мышления разработчика может включать в себя некоторые элементы образа мышления тестировщика, но чаще всего он скорее заинтересован в создании решений, чем в исследовании того, что может быть неправильно в этих решениях.

Коммуницируйте с разработчиками в контексте предполагаемого использования вашего API. Выясните у них, какие могут быть последствия, если использовать API не так, как написано в документации.

Удобство использования API. Практичность или же удобство использования с точки зрения API — это ряд следующих вопросов. Когда мы можем использовать различные методы и команды? Что если они будут соответствовать друг другу по неймингу и порядку параметров? Что будет, если некорректное использование API нарушит не только время прогона и скорость обратной связи, но и время компиляции?

Существует подход «Опыт разработчика» (DX — Developer Experience), применяющий концепции «пользовательского опыта» (UX — User Experience) к API, которыми пользуются разработчики. Опыт работы разработчиком (DX) можно несколько упрощенно описать как опыт пользователя (UX) для пользователей-разработчиков. Грубо говоря, формула DX могла бы выглядеть так:

DX = UX + Практики разработки

Цели использования API. Многие компании предлагают бесплатные API как готовый продукт, с открытым исходным кодом. Большинство современных сайтов используют по крайней мере несколько сторонних API. Многие задачи уже имеют готовые решения, предлагаемые сторонними разработчиками, будь то библиотека или услуга.

Таким образом, когда компания предлагает своим пользователям API, это значит, что она создала ряд специальных URL, которые в качестве ответа возвращают только данные.

В исследовательском подходе к тестированию очень важно задавать вопросы, в том числе о целях и предназначении создания API продукта.

Для чего он был разработан? Например, API Геолокации (Geolocation API) предоставляет отличные возможности для работы с данными местоположения, так что вы сможете отметить свое расположение на карте Google Map. Или еще один пример — Twitter API, который позволяет размещать последние твиты на вашем веб-сайте.

Для кого продукт может быть полезен? Хороший API прежде всего серьезно упрощает жизнь самим разработчикам и помогает им быстрее писать код. А также сделать сложные операции более простыми и понятными для клиентов и пользователей (здесь речь идет об опенсорсе, или же публичном, открытом API. Кроме того, он облегчает поддержку ПО. Сделайте API, с помощью которого ваши пользователи смогут создавать новые клиенты для приложения или же новые сервисы на его основе).

В чем эта полезность проявляется? Существуют разные категории полезности API: API для работы с документами, загруженными в браузер; API, принимающие данные от сервера (часто используются для того, чтобы обновить части веб-страниц); API для работы с графикой; аудио и видео API; API устройств; API хранения данных на стороне пользователя.

SDLC (жизненный цикл разработки ПО). Любое программное обеспечение развивается с течением времени. Это может потребовать различных версий для всех существенных изменений в приложении. Как новая версия приложения повлияет на ваше тестирование?

Как в связи с этим изменится работа вашего API? В каждой новой версии API реализованы изменения и новые возможности вашего приложения. API используются клиентами, поэтому должна выполняться обратная совместимость. Если новый функционал может ее сломать, но он необходим, реализовывать его надо в новой версии API. А значит, новые клиенты смогут использовать новую версию вашего API.

Может ли пользователь узнать версию этого API? Конечно! И как? Это зависит от того, какой метод управления версиями применяется на проекте. Например, разные интернет-гиганты используют различные типы версий:

  • разных URI — Twitter;
  • использование параметра запроса — Amazon;
  • использование заголовка — Microsoft;
  • использование Accept Header / Media Type — GitHub.

А что будет при удалении части функционала или замены API calls? В таких случаях выпускается новая версия API. Тогда версии маркируются согласно разным типам, описанным выше.

Будет ли удален неиспользуемый и устаревший код? Удаление предыдущих версий API с устаревшим кодом обеспечит хорошее тестовое покрытие, что, в свою очередь, гарантирует отсутствие или минимальные регрессии.

Гуглить все! Гугл сегодня — самый доступный источник любой информации. Встретилось незнакомое слово? Гугл — ваш лучший друг, товарищ и помощник!

Ответы на все ваши вопросы, как правило, прямо под рукой — всего в нескольких кликах от вас.

Сотрудничество с разработчиком, или Одна голова хорошо, а две — лучше. Если вы занимаетесь исследовательским тестированием API, вам точно нужна еще одна голова в помощь, а лучше несколько. Кто-то, кто уже хорошо знает продукт, кто-то, кто мог бы стать для вас достоверным и надежным источником информации о продукте. И, скорее всего, это будет именно разработчик, который пишет код для вашего продукта. Также это может быть другой тестировщик, который работает с продуктом дольше вас и знает его уже вдоль и поперек.

Используйте подход Strong-Style Pairing (парная сильная работа). Авторы — Maaret Pyhäjärvi (тестировщик) и Llewellyn Falco (разработчик). Смысл в том, чтобы выбрать себе сильного и знающего напарника для тестирования API. В целом основная идея заключается в том, что два человека находят оптимальное решение быстрее, чем один.

В парном тестировании, как и в парном программировании, две роли: драйвер и навигатор (или «водитель — штурман»). Если ваш напарник лучше генерирует идеи для тестирования — станьте его драйвером. Главная цель навигатора — доносить четкие идеи драйверу. Совместное создание mindmap — это отличный способ генерировать информацию, которая ляжет в основу исследовательского тестирования.

Этот подход активно используют в мобильной разработке.

Необходимость документации API. Документирование ПО — общая практика для всех разработчиков. Если специалист напишет исчерпывающую документацию, она поможет другим девелоперам понять его код, а тестировщикам качественно и быстро протестировать его.

Наиболее распространенный способ документирования REST-приложений — это документация с перечисленными в ней конечными точками (endpoints), описывающая список операций для каждой из них. Есть множество инструментов для того, чтобы сделать это автоматически: Swagger, ReDoc, DapperDox, OpenAPI Generator.

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

  • Качественно описывайте ваш продукт для новичков, использующих его.
  • Подробно изложите функционал продукта.
  • Отредактируйте и актуализируйте автоматически созданную документацию разработчиками (в Swagger’e, например).

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

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

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

Автоматизация помогает понять, какие параметры зависят друг от друга в ответе, следовательно, вы лучше разбираетесь в API, которое тестируете.

При создании автоматизации тестирования API ответьте себе на следующие вопросы:

  • Будут ли тесты использоваться многократно?
  • Какую ценность несет в себе автоматизация? Получаете ли вы новую информацию и реальные результаты тестов?
  • Сможете ли выделять время на поддержание тестов в актуальном состоянии?

Пишите свои тесты осмысленно. Представляйте, что написание кода — это создание баг-репорта. У хорошего кода есть структура, он оптимальный и читабельный.

Эвристики и мнемоники для тестирования API

ICEOVERMAD

Ash Winter, автор блога, в своей статье «Johnny Mnemonic — ICEOVERMAD» создал и описал мнемоническую схему для тестирования API сервиса, которая покрывает его ключевые области и является весьма эффективным и быстрым методом.

Существует некий набор критериев («эвристика»), которым продукт должен отвечать. Для оценки API можно определить разные составляющие: это будет зависеть от того, что из себя представляет ваш конкретный API (библиотека или REST-сервис).

Integration (интеграция)

  • Как пользователи будут интегрироваться с сервисом?
  • Через API или графический интерфейс?

Consumers (пользователи)

  • Кто является пользователем сервиса?
  • Конечный пользователь — человек или машина?
  • Какие проблемы пользователя решает ваш сервис?

Endpoints (точки доступа)

  • Какие у вас есть эндпоинты?
  • Эндпоинт единственный или есть еще?
  • Если их несколько, идет ли подключение через балансировщик?
  • Какой уровень защиты нужно обеспечить?

Operations (операции)

  • Какие операции выполняет бизнес через сервис?
  • Есть ли аналогичные функции в пользовательском интерфейсе?
  • У функции понятное название?

Volume (объем)

  • Какой объем запросов к нам придет?
  • Это будет постоянная нагрузка или редкие запросы с большим объемом данных?
  • Какой объем одной транзакции?
  • Архитектура кластерная или нет?

Error Handling (обработка ошибок)

  • Как сервис будет обрабатывать ошибки на стороне сервера?
  • Как сервис будет обрабатывать ошибки на стороне клиента?
  • Являются ли сообщения об ошибках информативными и подробными?
  • Как обрабатывается потерянная связь с базой данных?

RESTful

  • Обладает ли сервис характеристиками RESTful-сервиса?

Modularity (модульность)

  • Как распределяются компоненты в данном сервисе?
  • Как они взаимодействуют между собой?
  • Могут ли они существовать отдельно друг от друга?
  • Может ли один из модулей сервиса стать причиной сбоя в работе другого модуля?

Authentication (аутентификация)

  • Какая аутентификация используется?
  • Какой уровень защищенности?
  • Шифруется ли информация или отправляется в незащищенном виде?

Definitions (определения)

  • Что описывают данные на входе и выходе сервиса, что у нас есть?
  • Какие HTTP-методы используются?

Speed Loads

Мнемоническая схема от Daniel Donbavand, автора блога.

Security Testing (тестирование безопасности)

  • Fuzzing/фаззинг;
  • атаки невалидных входящих данных;
  • вредоносные входящие данные;
  • инъекционные атаки, межсайтовый скриптинг;
  • типы авторизации, необходимы для доступа к сервису.

Performance & Load Testing (тестирование производительности и нагрузочное тестирование)

  • Какую нагрузку способен выдержать сервис?
  • С какими типами нагрузки справляется сервис?
  • Достаточно ли быстро работает система?
  • Как система будет работать при возрастающей нагрузке?
  • Какая максимальная нагрузка, которую способна выдержать система?

Endpoints (эндпоинты)

  • Какие у вас есть endpoints?
  • Он единственный или их несколько?
  • Какие значения могут передаваться в каждом эндпоинте?

Error handling (обработка ошибок)

  • Как сервис будет обрабатывать ошибки на стороне сервера?
  • Как сервис будет обрабатывать ошибки на стороне клиента?
  • Какие сообщения об ошибках появляются?
  • Являются ли они информативными и подробными?
  • Как обрабатывается потерянная связь с базой данных?
  • Способен ли сервер к самовосстановлению?
  • Предпримет ли сервер повторную попытку к перезапуску?

Documentation (документация)

  • Существует ли документация о том, как работает сервер?
  • Насколько она понятна?
  • Покрывает ли она работу всего функционала вашего сервера?
  • Работает ли ваш сервер согласно описанной документации?
  • Корректно ли описаны в документации основные принципы и правила работы сервера?

Limits (лимиты, ограничения)

  • Какие лимиты установлены для каждого из эндпоинтов?
  • Какое максимальное и минимальное значения этих лимитов?
  • Есть ли какие-либо ограничения для запроса?

Order (порядок возвращения ответов)

  • Возвращаются ли ответы запросов в определенном порядке?
  • Возвращаются ли они по возрастанию, по убыванию, в алфавитном порядке?

Automation Checks (автоматические проверки)

  • Есть ли у вашего сервиса соответствующий лимит для модульных, интеграционных и приемочных тестов?

Datetimes (дата и время)

  • Возвращается ли время и дата в формате UTC?
  • Существует ли специфический формат даты и времени, который возвращается?

Status Codes (коды ответов)

  • Соответствуют ли возвращаемые статусы кодов ответов соответствующим HTTP статус-кодам стандарта w3?
  • Как можно подтвердить тот факт, что корректные статус-коды были возвращены с сервера?

Vader

Эвристика для тестирования REST API от Stuart Ashman, автора блога. Она дает отличную возможность разделить зоны ответственности, улучшает тестовое покрытие и отлично подходит для тестирования микросервисов.

Verbs (глаголы)

Get — запрашивает информацию из указанного источника и не влияет на его содержимое. Запрос доступен для кэширования данных и добавления в закладки. Длина запроса ограничена (максимальная длина URL — 2048 символов).

Post — используется для отправки данных, что может оказывать влияние на содержимое ресурса. В отличие от метода Get, запросы Post не могут быть кэшированы, они не остаются в истории браузера и их нельзя добавить в закладки. Эти запросы не ограничиваются в объеме.

Put — загружает содержимое запроса на указанный в запросе URI. Если по заданному URI ресурса нет, то сервер создает его, возвращая статус 201 (Created).

Patch — для частичного изменения ресурса.

Delete — удаляет все текущие данные на ресурсе, определённом URI.

Options — используется для описания параметров коммуникации между клиентом и сервером.

Authorization (авторизация)

Token — предоставляет информацию о событии аутентификации и идентифицирует пользователя.

API Key — уникальный идентификатор, используемый для аутентификации пользователя, разработчика или вызывающей программы в API. Однако они обычно используются для аутентификации проекта с помощью API, а не для пользователя.

Token / key / user&pass not in URL — токен / API-ключ / имя пользователя и пароль передаются не в URL.

Token / key / user&pass not logged — токен / API-ключ / имя пользователя и пароль неавторизованного пользователя.

Response data is auth’d (no multi / cross tenant data) — данные в ответе авторизированны (множественные или перекрестные данные отсутствуют).

Data (данные)

Serialization (сериализация) — процесс перевода какой-либо структуры данных в последовательность битов. Используется для передачи объектов по сети и для сохранения их в файлы.

Type (тип данных) — множество значений и операций над этими значениями.

Format (формат данных) — спецификация структуры данных, записанных в компьютерном файле.

Size (размер данных) — сколько данных содержит файл или сколько памяти он потребляет.

Pagination (пагинация) — порядковая нумерация страниц, которая в основном размещается вверху либо внизу страниц сайта.

Errors (ошибки)

Response codes (status codes — коды состояния HTTP) — часть первой строки ответа сервера при запросах по протоколу HTTP.

Message payloads (полезные сообщения, сообщения полей, набор полей) называется частью передаваемого пакета данных, в котором находится фактическое сообщение. Сетевые протоколы устанавливают максимальный предел длины полезной нагрузки.

Responsiveness (адаптивность)

Fail fast (Fail Fast — Fail Cheap! Принцип «провались быстро») — когда в приложении происходит ошибка, есть два диаметрально противоположных подхода к ее обработке:

  • Forgive! подход: приложение продолжает выполняться и старается минимизировать последствия ошибки.
  • Fail Fast! подход: приложение немедленно прекращает работу и сообщает об ошибке.

Timeouts (время ожидания) — параметр, связанный с совершением события и предназначен для оценки его завершения за определенное время.

Concurrency (конкурентность) — это свойство программы, при котором допускается одновременное выполнение нескольких вычислительных процессов, которые могут взаимодействовать друг с другом.

LH Traffic

Полезная мнемоническая схема от SZEKAR1, автора блога, которую можно объяснить как «левый трафик», или Lufthansa Traffic (для более простого запоминания) — left-handed traffic.

Leaky APIs (дырявые API) — это APIs, что предоставляют информацию, которую не должны были бы.

  • Должны ли видеть пользователи весь объем информации, который вы им отправляете?
  • Есть ли какая-либо конфиденциальная информация, которую не стоит показывать пользователям?
  • Обратите особое внимание на заголовки ответов — не содержится ли в них больше информации, чем должно быть?

Hidden APIs (скрытые API) — это APIs, которые, по мнению разработчиков, вообще никто никогда не должен обнаружить. Убедитесь в том, что эндпоинты, предназначенные для внутреннего использования, не находятся в свободном доступе.

  • Используете ли вы для документирования вашего API Swagger или любой другой подобный ресурс?
  • Что, если в нем описаны не только публичные эндпоинты?
  • Не содержится ли в теле ответа для других запросов URL на более детальное описание вашего ресурса или приватного, предназначенного только для внутреннего использования, API?
  • А что по поводу логов на сервере?
  • Много ли в них приватных APIs, которые вы бы не хотели показывать клиентам?

Tampering Requests/Responses (поддельные запросы/ответы)

  • Где ваша команда размещает валидацию параметров, которые отправляются в API-запросах?
  • Если ответ от сервера может быть перехвачен — ваш фронтенд может подвергнуться атаке.

Authorization / Authentication (авторизация / аутентификация)

  • Какой тип авторизации поддерживает ваш API?
  • Можете ли вы обойтись без него?
  • Можете ли использовать другие?
  • Если используется комбинация: имя пользователя / пароль, отправляется ли она в формате plain text?
  • Как часть самого URL или как payload?
  • Что если комбинация имя пользователя / пароль недоступна?
  • Какой статус-код возвращается?
  • Какая ошибка выводится в сообщении?
  • Она аналогична той, что вы получаете в случаях ввода неправильного имени пользователя и неправильного пароля?
  • Можете ли вы получить весь список имен пользователей?
  • Какое время ответа для допустимой/недопустимой комбинации?
  • Можете ли вы получить доступ к ресурсам, на которые у вас нет прав для просмотра?
  • Если вы используете в запросах токены, могут ли они использоваться повторно?
  • Какое время жизни у ваших токенов?
  • Можно ли их сгенерировать самостоятельно?

Fuzzing (Fuzz testing — фаззинг-тестирование). Начните фаззинг-тестирование вашего API с использования невалидных и случайных данных, отправки неожидаемых системой значений в вашем API и обратите внимание на результаты тестов — не сломают ли они систему? Протестируйте с разнообразными наборами данных, цифр, букв, строк, символов.

Forgotten (забытое)

  • Не осталось ли каких-либо дефолтных заголовков вне вашего запроса?
  • Доступен ли ваш Swagger (или другой аналогичный сервер для генерации и хранения API-документации)?
  • Является ли он публичным?
  • Возможно, он доступен только для вашего Dev-окружения, а затем кто-то мог забыть отключить его для production?

Injections (инъекции). Все мы знакомы с SQL-инъекциями, верно? Можно также попробовать применить инъекции команд ОС («внедрение кода») для разных точек входа запроса: из заголовков, через параметры, в теле запроса (не ограничиваясь только XML или JSON).

Content-Type (заголовок-сущность)

  • Соответствует ли Content-Type вашего заголовка типу MIME, который вы отправили в запросе?
  • Какой будет ответ приложения на полученный неподдерживаемый Content-Type?
  • Поддерживаете ли вы более одного Content-Type (например, JSON и XML)?
  • Одинаковые ли ответы для обоих кейсов?
  • Соответствует ли обработка запросов бизнес-логике работы продукта?
  • В случае передачи файлов проверяете ли вы только Content-Type и/или расширение файла?

HE MAD

Моя эвристика для тестирования REST API. Удобный вариант для проверки микросервисов.

Немного о проекте, в котором я работаю. SignNow — высоконагруженный продукт, позволяющий редактировать и подписывать PDF-документы. Вы можете загрузить документ, определить список людей или организаций, которые должны его подписать, и отправить им на подпись. Главная фича продукта — это так называемая e-signature, или электронная подпись.

Конечно, сейчас я очень кратко описала вам основной функционал. И, конечно же, есть много дополнительных фич, призванных облегчить жизнь наших пользователей. Собственно, сегодня это ведущий сервис электронной подписи для корпоративного и командного использования на рынке США. Наши клиенты — частный бизнес, государственные учреждения и благотворительные организации в Соединенных Штатах, Европе и Австралии.

Над проектом трудится более 10 команд, включая фронтенд, бэкенд, кроссфункциональную команду, команды мобилочек и интеграции, а также QA Automation, бизнес-аналитики и саппорт. Одних только QA всех типов, видов и подвидов больше 25 человек. Команды в большинстве своем небольшие — 6–12 человек, на одну команду приходится от одного до трех тестировщиков.

QA бэкенд-команд часто взаимодействуют между собой, создавая, обсуждая и совершенствуя API Postman коллекции друг друга, когда функционал пересекается. Поэтому после получения в работу нового объемного функционала я, помимо стандартных техник тест-дизайна, перехожу к исследовательскому тестированию. Первое время мне очень помогали ICEOVERMAD и Vader, пока я не выработала свой собственный подход, учитывая все особенности и технические нюансы нашей микросервисной архитектуры. Именно тогда и сложился в голове весь пазл, который получил название HE MAD.

Для ее запоминания можно использовать аббревиатуру, состоящую из первых букв HE MAD: Headers — Error Handling (Status Codes) — Methods — Authorization/Authentication — Data (Body).

Headers (заголовки)

Cache-Control — используется для задания инструкций кэширования как для запросов, так и для ответов. Они однонаправленные: заданная инструкция в запросе не подразумевает, что такая же инструкция будет указана в ответе.

Accept-Charset — запрос HTTP сообщает, какую кодировку клиент может понять. Через согласование контента сервер выбирает один из предложенных вариантов, использует его и информирует клиента о своем выборе в Content-Type ответном заголовке.

WWW-Authenticate и Proxy-Authenticate заголовки ответа, которые определяют методы, что следует использовать для получения доступа к ресурсу. Они должны указывать, какую схему аутентификации использовать, чтобы клиент, желающий авторизоваться, знал, какие данные предоставить.

Authorization — включает в себя данные пользователя для проверки подлинности пользовательского агента с сервером обычно после того, как сервер ответил со статусом 401 «Не авторизован» и заголовком WWW-Authenticate.

Content-Type — используется для того, чтобы определить MIME-тип ресурса. В ответах сервера заголовок Content-Type сообщает клиенту, какой будет тип передаваемого контента.

Error Handling/Status Codes (обработка ошибок/статус-коды)

  • Как сервис будет обрабатывать ошибки на стороне сервера?
  • Как сервис будет обрабатывать ошибки на стороне клиента?
  • Какие сообщения об ошибках появляются?
  • Как обрабатывается потерянная связь с базой данных?

Methods (методы)

  • Get
  • Post
  • Put
  • Head
  • Patch
  • Delete
  • Options

Authorization/Authentication (авторизация/аутентификация)

  • Какой тип авторизации поддерживает ваш API?
  • Что если комбинация имя пользователя / пароль недопустима или невалидна?
  • Какой статус-код возвращается?
  • О какой ошибке говорится в сообщении?
  • Можете ли вы получить доступ к ресурсам, на которые у вас нет прав для просмотра?
  • Если вы используете в запросах токены — могут ли они использоваться повторно?
  • Какое время жизни у ваших токенов?

Data / Body (данные / тело запроса)

Тело бывает не у всех запросов: запросы, собирающие ресурсы, такие как Get, Head, Delete или Options, в нем обычно не нуждаются. Но некоторые запросы отправляют на сервер данные для обновления, как это часто бывает с Post, Put и Patch.

Вкладка Body в Postman позволяет указать данные, которые необходимо отправить с запросом. Есть возможность выбрать тип данных, необходимых для тела запроса — FormData, URL-encoded, raw, binary, GraphQL.

В теле запроса можем передавать файлы. Это помогает запускать коллекции, которые содержат запросы, где необходима загрузка файлов. В документации все необходимые параметры Params, Headers, Body прописаны, а также указано, в каком формате эти данные должны быть переданы.

Резюме

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

Машина сможет найти лишь те проблемы, которые мы можем предсказать и запрограммировать. И для этого, как обратная сторона автоматизации, появляется импровизационное тестирование, а именно исследовательское. Идеальное исследовательское тестирование подразумевает, что мой следующий тест будет полностью сгенерирован моими собственными идеями и подходами, без каких-либо предварительных заготовок и сценариев. Абсолютно сценарное тестирование и абсолютно исследовательское — две стороны одного и того же процесса. Они являются полностью совместимыми, отлично взаимодействуют и компенсируют недостатки друг друга.

Я не призываю вас стать яростными адептами эвристик и мнемоник для тестирования вашего API. Пробуйте. Исследуйте. Открывайте. Создавайте. Используйте свои навыки и интуицию, а также опыт и подход других специалистов. И обещаю, что это поможет обнаружить информацию, о которой вы раньше даже не догадывались. Которую не удалось обнаружить, используя стандартные подходы и техники тестирования.

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

Список полезных ресурсов


Чтобы не пропустить новые статьи Тони Тараненко — подпишитесь на нее в телеграм-боте Ленты DOU.

Похожие статьи:
У свіжому дайджесті DOU News обговорюємо арешт Дурова, зростання ІТ-експорту з України, багато новин про штучний інтелект, українські...
Правозахисний центр «Принцип» презентував навігатор для військових, ветеранів та їхніх сімей. У мобільному застосунку можна...
В выпуске: выход новых nginx, ubuntu, redis; хороший сборник cheat sheet’ов, как запустить свой Chaos Monkey в Amazon и Continious Delivery anti-patterns. Новости,...
Легалізуються за кордоном і звільняються ті, хто давно на бенчі, — такі основні причини зменшення кількості фахівців...
У випуску: як працює Dependency Injection, Software Design Patterns в Symfony, конференція PHP fwdays’18. Основне PHP Versions Stats — 2018.1 Edition — статистика...
Яндекс.Метрика