Автоматизация тестирования REST API на сегодняшний день является актуальной темой в интеграционном тестировании. В этой статье мы поговорим о программе Postman, применяемой для тестирования REST API, рассмотрим несколько интересных методов написания автотестов и на примере реального проекта API «Яндекс.Словарь» разберем несколько тестов.
Нам понадобится
Для того, чтобы начать тестировать «Яндекс.Словарь», нам понадобится:
-
- Знание основ программирования. Достаточно владеть такими понятиями, как:
- переменные,типы данных,операторы,массивы,условия,логические операторы и вычисления (вспоминаем курс матлогики),область видимости.
Для чего-то более сложного и интересного, уже необходимо знать про
- Знание основ программирования. Достаточно владеть такими понятиями, как:
- Понимание REST API. Об этом хорошо рассказал в своей статье Андрей Шальнев.
- Postman – программа, в которой будут создаваться автотесты.
- Документация. Документация – это своего рода инструкция, из которой узнаем, какие функции необходимо протестировать.
- Ключ для «Яндекс.Словарь». Специальный ключ для использования «Яндекс.Словарь» можно получить быстро и бесплатно в сервисе.
Планирование в тестировании
Прежде чем начать писать код, мы должны ответить на следующие вопросы: «какие методы будем тестировать», «как будем тестировать» и «какие трудности могут возникнуть».
Какие методы будем тестировать? На этот вопрос нам поможет ответить документация. В документации «Яндекс.Словарь» описаны два метода (getLangs и lookup) и несколько параметров к каждому из методов.
Как будем тестировать? Для того, чтобы выбрать технику тестирования, необходимо проанализировать параметры метода API. Значения параметров бывают разными, это может быть число, слово, элемент из списка значений и другие типы данных. К каждому параметру нужен свой подход: например, если параметр – это число с допустимым максимальным значением, то что произойдет при отправке в запросе числа, превышающего это значение? Если API работает правильно, то в ответе мы увидим ошибку с этим параметром; отсутствие ошибки будет означать, что API работает неправильно. Для написания тестов значений параметров можно использовать различные техники тест-дизайна (например, классы эквивалентности, граничные значения и техники парного тестирования).
Какие трудности могут возникнуть? Нельзя недооценивать скорый дедлайн, проблемы сервера с API, проблемы с интернетом и внезапное изменение API. Недостаток опыта тестирования и знаний JavaScript приведет к увеличению времени на написание автотестов. Таким образом, закладывая время на разработку тестов, старайтесь все это учесть для точной оценки сроков и качественного тестирования.
Хорошая структура – быстрый анализ ошибок
Пишите свои тесты осмысленно. Представляйте, что написание кода – это создание баг-репорта. Хороший код отличает структура, оптимальность и читаемость.
Читаемость кода достигается несколькими путями. Упомянем лишь часть из них:
- используйте отступы в областях видимости функций, циклов и условий;
- пишите понятные и лаконичные имена переменных и функций;
- не перегружайте условные конструкции логическими выражениями;
- используйте простые функции вместо сложных встроенных функций языка программирования.
Оптимальность кода достигается тщательным продумыванием каждой строчки и отсечением всего лишнего; при этом алгоритм должен выполняться за минимальное число шагов.
Для улучшения структуры и оптимальности кода, а также сокращения времени на анализ ошибок FAIL, я хочу предложить вам использование двух методов – вложенных условий и assert’ов.
Метод вложенных условий
Суть этого метода в следующем: все проверки, которые можно было написать на вкладке «Tests», вы пишите во вложенных условиях if-else. Этот метод мне нравится тем, что «если что-то сейчас не работает, то дальше проверять не имеет смысла». Это значит, что вы экономите время выполнения проверки метода API, а при правильном заполнении ассоциативного массива tests[] можете сразу понять, что именно сломалось.
Представьте гирлянду с последовательно соединенными лампочками: если одна лампочка перегорает, то не работает вся цепь. Здесь принцип такой же, только лампочки горят до первой поломанной. Не делайте из условий if «параллельные лампочки» – вам сложно будет разобраться, где именно появится ошибка.
Приведу пример плохого написания кода (не используются остановки выполнения автотеста):
Для того, чтобы этот метод работал правильно, вы должны расставить приоритет своим тестам, выяснить последовательность их выполнения и определиться с тем, что имеет смысл проверять даже если что-то сломалось (а также и то, что проверять не нужно).
Например, самый высокий приоритет будет иметь код статуса. Если вы ожидали код 200, а пришло что-то другое (4хх или 5хх), то проверку можно не продолжать – выводим сообщение об ошибке «код ответа не 200». Далее имеет смысл проверить, заполнен ли хоть чем-то ответ: если ответ пуст – выводим ошибку.
Ошибка в данном случае подразумевает следующие действия: мы создаем ассоциативный массив и присваиваем ему значение false, а все логические проверки будут происходить в условии if.
Реализация метода «вложенных условий» выглядит так:
Метод assert’ов
Этот метод будет имитировать работу assert, так как в JavaScript нет этой встроенной функции или ключевого слова. Для понимания способа реализации этого метода на практике я расскажу о том, как assert работает в других языках программирования.
Assert – это принудительный вызов ошибки, исключения, остановки работы программы; при этом может передаваться пользовательский текст ошибки. В программировании assert используется по такому алгоритму: если произошла ошибка, то вызвать исключение с описанием этой ошибки.
В JavaScript это можно реализовать при помощи следующего алгоритма:
- в условие if записываем логическое выражение, истинное при неверных данных;
- в if записываем ассоциативный массив tests[] с ключом-описанием ошибки и значением false;
- после tests[] в условии if вызываем return, который принудительно остановит дальнейшее тестирование.
Не забывайте про приоритет тестов для их логически правильного выстраивания. В данном методе тесты слабо зависят друг от друга, т.е. вы можете сначала проверить, пустое ли тело ответа, затем – какое вернулось значение у параметра «часть речи», а потом – код 200. При первой найденной ошибке метод завершает свою работу и отправляет эту ошибку на вкладку Tests.
Код автотеста с методом assert’ов будет выглядеть так:
Для того, чтобы узнать, какие проверки были отработаны верно, после каждого if необходимо дописать else c tests[«ключ»] = true.
Какой метод лучше?
Оба метода хороши по-своему.
Плюсом метода вложенных условий является возможность вывода нескольких ошибок одновременно. Использование ассоциативного массива и отсутствие принудительных остановок return позволяет полностью проверить ответ и остановить проверки только на определенных уровнях вложенности. В итоге вместо одной ошибки можно получить три на вкладке Tests. Также этот метод помогает понять, какие параметры зависят друг от друга в ответе, – следовательно, вы лучше понимаете и разбираетесь в API, которое тестируете.
У такого метода есть и недостатки. К примеру, если у вас есть 30 проверок, то нужно ли делать 30 вложенных условий? Нет, здесь необходимо держать баланс между количеством и качеством. Один из приемов, позволяющий обойти большое количество проверок, – это разбиение вложенности на группы. Так, если признак не влияет на работу других признаков, то проверки можно оставлять на одинаковой вложенности; в противном случае необходимо делать вложенное условие. Если уровень вложенности превышает 5, то целесообразно принудительно остановить процесс и разбить тесты на группы, так как большая вложенность проверок затрудняет понимание и читаемость кода. И кстати, не жалейте отступы внутри условий, иначе ваш код станет трудночитаемым!
В методе assert’ов меньше проблем с читаемостью кода по сравнению с методом вложенных условий. Все тесты расположены на одном уровне. Реализация этого метода проще, так как метод вложенных условий требует тщательного продумывания приоритета проверки в условии if.
Основной минус метода assert’ов заключается в том, что автотест сразу прекращает свою дальнейшую работу после обнаружения первой ошибки в проверках. Допустим, если в ответе придет пять ошибок, то об этих ошибках вы будете узнавать последовательно, по мере исправления предыдущей проверки и повторного запуска автотеста.
В итоге оба метода свелись к выбору между «читаемостью кода», «легкостью и скоростью реализации автотеста» и «количеству найденных ошибок при одном запуске теста». Если вы хотите быстро писать автотесты, но при этом готовы исправлять ошибки по мере их обнаружения, то используйте метод assert’ов. Если у вас есть время на продумывание структуры проверок, выявление зависимостей параметров в ответе, и вы хотите получить все ошибки сразу – используйте метод вложенных условий.
Использование любого из рассмотренных методов при обнаружении хотя бы одной ошибки позволяет сократить время выполнения автотестов для проверки API. При написании же автотеста без этих методов вы будете вынуждены выполнить его до конца со всеми проверками, которые можно было бы и не делать из-за уже найденных ошибок.
Практика написания тестов методом вложенных условий
Настало время приступить к написанию автотестов! Давайте попробуем сделать что-то посложнее, применив метод вложенных условий.
Для тестирования метода lookup отправим параметры lang = «ru-ru» и text = «лягушка» и проведем тесты на код 200, на непустое тело ответа и на то, что «лягушка» – имя существительное.
В данном примере получилось три условия if-else, которые вложены по приоритету. Это не все проверки, которыми можно покрыть данный метод, дальнейшее усложнение зависит от знаний и желаемого качества тестового покрытия.
Для тех, кто не знает разницу между «==» и «===», полезно прочитать это и вот это.
Первая сложная строка в примере – var responseBodyJSON = JSON.parse(responseBody). Дело в том, что ответы от сервера приходят в формате JSON. JSON – это объект, и если вы имеете представление о классах и объектах, то сразу поймете, о чем идет речь. Если же предмет разговора вам непонятен, то его можно объяснить с помощью примера: у вас есть большой платяной шкаф, а внутри него – выдвижные ящики, дверки, вешалки и платья. Ящики, дверки, вешалки – это функции шкафа, а платья – параметры; все в целом – это объект. В Postman responseBody – это не JSON (объект), а строка, но преобразовать в JSON (объект) можно как раз функцией JSON.parse().
Вторая сложная строка – var strfromJSON = responseBodyJSON.def[0].pos, это обращение к нужному параметру в объекте JSON. Например, если в нашем шкафу есть 5 выдвижных ящиков, а нужная вещь находится во втором ящике, то доступ к этой вещи будет выглядеть следующим образом: «шкаф -> выдвижные ящики -> первый выдвижной ящик -> вещь». В документации к «Яндекс.Словарь» можно прочитать о параметрах ответа JSON. Def – массив словарных статей (соответственно, def[0] – первая словарная статья). Pos – часть речи.
Для более наглядной иллюстрации работы метода вложенных условий я покажу его реализацию на практике, представив два примера: когда «все работает», и когда сервер прислал пустое «тело ответа».
По клику на картинку откроется полная версия.
Все, что следует после FAIL, не проверяется и не выводится; тестирование останавливается.
Заключение
В данной статье я рассказала о тестировании API «Яндекс.Словарь» при помощи Postman, JavaScript, GET запроса и JSON объекта, а также объяснила, как можно облегчить себе жизнь после FAIL при помощи метода вложенных условий или метода assert’ов.
Применяйте все это на практике и получайте хорошие результаты! 🙂