Разделы портала

Онлайн-тренинги

.
Исследовательское тестирование API, часть 3
19.06.2019 00:00

Автор: Майкл Болтон (Michael Bolton)
Оригинал статьи: http://www.developsense.com/blog/2018/07/exploratory-testing-on-an-api-part-3/
Перевод: Ольга Алифанова

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

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

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

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


Люди используют ПО, чтобы что-то сделать – неважно, идет ли речь о конечных пользователях, общающихся с продуктом через интерфейс, или разработчиках, имеющих доступ через API. У всех у них есть задачи, которые нужно выполнить. Итак, что же может быть нужно пользователю API? (Эвристика Product Factors/Operations; Test Techniques/Scenario Testing).

Пользователь API хочет получить данные, спровоцировать какое-то событие, или внести изменения. Все, что происходит или меняется в продукте, обусловлено специальными функциями в его коде. Какие функции выполняет продукт? (Эвристика Product Factors/Functions). Я выясняю это, читая документацию на продукт и API, если она мне доступна, или изучая исходный код, если это возможно (эвристика Project Environment/Information). В случае отсутствия документации и доступа к коду я могу попросить помощи у разработчиков и дизайнеров (эвристика Project Environment/Developer Relations).

Я помечаю для себя информацию – возможно, через ментальную карту, а может, как маркированный список или таблицу. Процесс ведения заметок помогает закрепить то, что я узнал. Помимо этого я хочу также отмечать несоответствия между разными источниками информации. Иногда разные люди говорят по-разному об одном и том же. Некоторые высказывания противоречат тому, что указано в требованиях или спецификациях. Когда нечто подобное происходит, рождаются баги. Я собираю все высказывания о продукте и том, что он должен делать, и ищу противоречия (эвристика Test Techniques/Claims Testing).

Затем я подведу итоги всего, что я уже знаю. К каким функциям API позволяет получить доступ? Пользователь API хочет получить какую-то ценность, взаимодействуя с продуктом, и эту ценность можно выразить в терминах критериев качества (эвристика Quality Criteria/Capability). Что может пойти не так в ходе использования этих функций, угрожая критериям качества?

Какими протоколами вызываются эти функции (эвристика Product Factors/Interfaces)? Есть ли что-нибудь вроде настройки или авторизации, что должно произойти до вызова API? Что, если это не произойдет? Помечу себе, что надо попробовать так сделать (эвристика Test Techniques/Flow Testing). Подумав о том, что происходит до, я начинаю думать о том, что происходит после. Нужна ли какая-то очистка после вызова API (эвристика Product Factors/Time)? Нужно ли сохранить или удалить данные?

Рассматривая набор доступных функций, я попробую использовать небольшую выборку функций, о которых я знаю (эвристики Test Techniques/Function Testing; Test Techniques/Claims Testing). Попробую сделать что-нибудь простенькое, используя инструмент, позволяющий взаимодействовать с API напрямую (в наши дни это Postman), или посредством быстрых вызовов через IRB (Ruby-интерпретатор). Делает ли продукт то, что должен? Может ли он работать (эвристика Quality Criteria/Capability).

Начну с простых репрезентативных данных на входе, а затем начну исследовать пределы и границы, о которых я узнал от людей или из документации (эвристика Test Techniques/Domain Testing). Я буду вводить строки огромной длины, передавать большие или преднамеренно битые данные. Я оставлю пустыми обязательные поля в вызове, добавлю лишние придуманные поля, введу буквы там, где ожидаются цифры, и буду передавать символы или специальные знаки там, где ожидаются только обычные буквы. Если это Web-приложение, я, возможно, сконцентрируюсь на наборах символов, ассоциирующихся с межсайтовым скриптингом, SQL-инъекциями, или другими рисками безопасности (эвристика Quality Criteria/Security).

Если я делаю что-то, что должно спровоцировать обработку ошибки, происходит ли эта обработка? Возвращает ли продукт код ошибки? Продолжает ли после этого делать то, что он должен делать (эвристика Test Techniques/Claims Testing; Quality Criteria/Reliability/Robustness)? Я обращаю особое внимание на ситуации, когда поведение продукта противоречит документации или высказываниям людей о нем (эвристика Test Techniques/Claims Testing).

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

Затем я беру паузу и вспоминаю, что есть разница между продуктом, делающим то, что он должен, и кажущимся таковым. На каждом шаге своего пути я хочу иметь возможность максимально тщательно наблюдать за состояниями продукта. Существуют ли какие-то особые вызовы функций API, которые можно использовать для наблюдения или контроля за состояниями продукта до, во время и после обычных вызовов (эвристика Quality Criteria/Development/Testability)? Они могут отсутствовать в публичной документации, но можно спросить разработчиков (эвристика Project Environment/Developer Relations) или посмотреть в исходный код (эвристика Project Environment/Information).

Когда я размышляю о тестируемости подобным образом, это приводит меня к вопросу, есть ли в продукте логирование? Надо проверить. Соответствует ли формат логов другим логам системы? Грамотные логи помогут ускорить и упростить тестирование, и позволят перейти к более глубокому тестированию (эвристика Quality Criteria/Development/Testability). Если логов нет, а менеджмент и разработка сопротивляются их внедрению, я помечу это на будущее, когда буду создавать автоматизированные проверки: возможно, мне понадобятся более подробные и детализированные логи для них.

Я перешел от размышлений о функциях к размышлениям о тестируемости, поэтому я дергаю свой разум за поводок и заставляю его вернуться к функциям. Какие услуги оказывают эти функции системе? Из каких блоков и модулей система состоит (эвристика Product Factors/Structure)? Если я еще не сделал этого, я начинаю набрасывать диаграмму структуры продукта, которая будет использоваться для направления моего понимания продукта. По мере развития этого понимания я буду делиться диаграммой с коллегами, дабы убедиться, что мы все понимаем одинаково, и помочь пополнить наши знания о структуре продукта. Я также могу разместить копию этой диаграммы на видном месте и попросить людей сообщить мне, если они заметят, что в ней что-то не так. Периодически я буду проверять и пересматривать эту схему.

Размышляя о частях системы, я прихожу к вопросу "от каких частей системы зависят функции API"? В методологии Rapid Software Testing то, от чего зависит наш продукт, и что не находится под контролем нашего проекта, называется платформой (эвристика Product Factors/Platform). Платформы могут включать в себя операционную систему, браузер, фреймворки приложений, сторонние библиотеки, нечто созданное внутри компании или в другом проекте. Они также могут относиться к хардварным элементам – дисплеям, клавиатурам, мышкам, тач-экранам, принтерам и другой периферии. Я создам списки платформных зависимостей, чтобы подготовиться к более глубокому покрытию продукта.

Вернусь к исполнению функций. Большая часть функций делает что-то с чем-то, то есть с данными. Какие данные я могу передавать через API? В каком формате? Что на это может отвечать API? Как структурированы ответы (эвристика Product Factors/Data)? Ответы на эти вопросы повлияют на мой выбор инструментов для более глубокого тестирования (эвристика Project Environment/Equipment and Tools).

Дает ли API доступ к базе данных? Если это так, и если я концентрируюсь на тестировании функций API, я могу использовать прямой доступ к базе как оракул (эвристика Test Techniques/Function Testing).

Размышления о базах данных подталкивают меня к тому, чтобы задуматься о хранении данных и их качестве. Подумаю немного о качестве данных и о том, какие данные я могу использовать или сгенерировать для автоматических проверок (эвристика Test Techniques/Domain Testing; Test Techniques/Automated Checking). Если я хочу исследовать риски, связанные с качеством данных, прямое взаимодействие с базой данных может быть эффективнее, чем попытки получить данные через функции API. Конечно, я могу делать и то, и это, но мне понадобятся разные инструменты (эвристика Project Environment/Equipment and Tools).

Изучая использование API, я делаю ровно то, что любой его пользователь – как правило, разработчик – будет делать, чтобы разобраться в нем, разве что я более кропотлив (эвристика Test Techniques/User Testing). Как и пользователь, я делаю ошибки – иногда преднамеренно, а иногда случайно. Насколько сложным для разработчика будет правильное использование API? Насколько легко сделать в нем ошибку, использовать его так, чтобы получить дезориентирующие, двусмысленные или сбивающие с толку результаты (эвристика Quality Criteria/Usability Test Techniques/Risk-Based Testing)?

Я воображаю набор задач программиста, которые нужно реализовать с использованием API. В то же самое время я представляю себе человека, занятого этими задачами – роль. Возможно, не все пользователи API – опытные программисты, поэтому имеет смысл создать роль "программиста-новичка" (эвристика Test Techniques/User Testing). Что, если я буду делать ошибки, которые делают начинающие разработчики, и запрошу что-нибудь, что не поддерживается API? Что, если я предоставлю плохие, битые данные, структуры с отсутствующими элементами, данные в неверном формате, или символы, которые могут использоваться за рубежом (эвристика Quality Criteria/Localizability)? Сообщит ли продукт об ошибке?

Хорошо ли все очищается после сообщения об ошибке? Грамотно ли обрабатываются условия для ошибки (эвристика Quality Criteria/Reliability/Error Handling). Как условия ошибки передаются пользователю API – приложению, которое его вызывает, и человеку, пишущему это приложения? Есть ли коды ошибок для облегчения разбирательств с проблемами (эвристика Quality Criteria/Development/Supportability), читабельные строки или структуры данных? Соответствуют ли они документации (эвристика Quality Criteria/Usability)? Достаточно ли они эффективны и понятны, или же они громоздкие, нечеткие, содержат опечатки, или смущают пользователя каким-то иным способом (эвристика Quality Criteria/Charisma)?

Некоторые API используются для атомарного взаимодействия – единичных вызовов от сервиса с единичными ответами на них. Другие больше похожи на разговор – они сохраняют данные или поддерживают продукт в определенном состоянии между запросами. У разговора есть свои риски – что будет, если я прерву его? Что произойдет, если я пропущу какой-то вызов или ответ (эвристика Test Techniques/Flow Testing)? Что будет, если я буду варьировать последовательность действий в этом диалоге (эвристика Product Factors/Time)? Заявлял ли кто-нибудь что-нибудь о таймаутах – неважно, неформально или посредством документации (эвристика Test Techniques/Claims Testing)?

Насколько долгой может быть пауза в этом разговоре (эвристика Product Factors/Time)? Что произойдет с состоянием системы или данных, если поставить наш диалог на паузу на какое-то время? Что будет, если я попытаюсь продолжить прерванный диалог (эвристика Quality Criteria; Reliability).

Думая о последовательности действий, я начинаю размышлять о времени в целом. Как долго система обрабатывает запрос к API и возвращает результат (эвристика Product Factors/Time)? Инструменты помогают сделать время ожидания явным, но я не доверяю первому результату. Так как через инструментарий сделать это очень легко, я провожу несколько быстрых тестов, чтобы понаблюдать результаты запроса несколько раз. Если в них есть существенные вариации, я помечаю это – возможно, это баг, или же идея для более глубокого тестирования.

Заявлял ли кто-нибудь что-то о производительности (эвристика Project Environment/Information)? Я, конечно, могу опираться на эти заявления, но для тестирования производительности они мне не так уж и нужны. Я буду взаимодействовать с продуктом, собирая информацию о его производительности, и включу ее в свой отчет.

Помимо API, в продукте могут быть другие интерфейсы – GUI или командная строка. Я посмотрю на то, как они работают, с целью поиска расхождений между их поведением и поведением API (эвристика Product Factors/Interfaces). Несоответствие продукта самому себе – это мощный оракул.

Мысли об интерфейсах, с которыми может взаимодействовать человек, наводят меня на идеи о других интерфейсах. API взаимодействует с определенными компонентами продукта, а продукт неизбежно общается с другими продуктами – операционной и файловой системой, сторонними фреймворками и библиотеками, сетями, принтерами, портами, Bluetooh… Эти интерфейсы дают доступ к платформам, от которых зависит продукт (эвристика Product Factors/Platform).

Что, если какая-то из этих зависимостей отсутствует? Что будет, если я лишу продукт чего-то, что необходимо ему, запретив доступ к файлам или базам данных (эвристика Test Techniques; Stress Testing)? Продолжит ли он работу (эвристика Quality Criteria; Reliability)?

Размышления о надежности заставляют меня подумать о том, как будет вести себя продукт под нагрузкой (эвристика Quality Criteria; Performance). Могу ли я подвергнуть его стрессу, перегружая его большими объемами данных в отдельных полях, или большим количеством запросов (эвристика Test Techniques; Stress Testing)? Мне для этого непременно понадобятся инструменты (эвристика Project Environment/Equipment and Tools).

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

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

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

Все это – тестирование! Я не только тестирую с целью найти баги – я тестирую, чтобы узнать, как мне тестировать продукт. Если я буду использовать автоматические проверки как часть стратегии для быстрого изучения деталей продукта, мне нужно тестировать, чтобы узнать, как разрабатывать эти проверки. Это исследовательский процесс! Заметьте, что зачастую одна идея вытекает из другой. Тестирование – это исследование по своей природе.

Применяю ли я исследовательский подход к тестированию API? Да! Если я его тестирую – я по определению применяю исследовательский подход! Если я делаю что-то еще, то это, скорее всего, автоматические проверки. Но я не могу приступать к созданию отличных проверок, не проведя всей подготовительной исследовательской работы.

Обсудить в форуме