Привет! Я Владимир Пасюга, QA Engineer в NIX. Общий опыт в IT у меня составляет 7 лет, из них 2,5 года я был мануальным тестировщиком в биомедицинском проекте, который включал и UI, и API-часть. Сейчас занимаюсь автоматизированными тестами API в приложении для медицинской сферы.

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


Коротко о базовых понятиях

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

На сегодняшний день существует два основных подхода к построению программного интерфейса веб-приложений: REST (RESTful) API и SOAP API. Если сравнить HTTP-запрос с бумажным носителем, то можно сказать, что REST API в большинстве случаев передает простые записки и время от времени — письмо в конверте (возможно, написав при этом часть послания и на самом конверте). В свою очередь, SOAP API отправляет все инструкции в подробном письме стандартного вида, используя конверт (единичный HTTP-запрос) лишь как средство доставки.

Когда клиенты и серверы работают только в веб-среде, информация об объектах не важна и нет транзакций с несколькими вызовами, применяют REST API. Если же необходимо соблюсти строгий контракт между сервером и клиентом, обеспечить те самые транзакции с несколькими вызовами с высокой безопасностью и нет проблем с пропускной способностью, тогда микросервисы настраивают на SOAP API.

Какие инструменты нужны для тестирования API?

Отсутствие элементов UI-интерфейса с непривычки может ввести QA-специалиста в ступор: нет ни кнопок, ни полей, ни понятного формата обращения к сервисам. Облегчают взаимодействие с API специальные инструменты. Наиболее популярные среди них — SoapUI и Postman.

SoapUI. Приложение с открытым исходным кодом для тестирования Soap и Rest API. SoapUI был первоначально выпущен для SourceForge в сентябре 2005 года. Это бесплатное программное обеспечение с публичной лицензией Европейского Союза. Начиная с первого выпуска, SoapUI был загружен более 2 000 000 раз. Он полностью построен на платформе Java и использует Swing для пользовательского интерфейса (то есть SoapUI — кроссплатформенный). Его функциональные возможности включают проверку веб-службы, запуск, разработку, моделирование и макетирование, функциональное тестирование, тестирование нагрузки и соответствия.

Компания-разработчик программного обеспечения SmartBear также создала коммерческую версию SoapUI Pro (ныне носит название ReadyAPI), которая в основном фокусируется на функциях, предназначенных для повышения производительности. SoapUI может тестировать веб-сервисы SOAP и REST, JMS, AMF, а также выполнять любые вызовы HTTP(S) и JDBC. Для написания автоматизированных скриптов используется язык Groovy.

Postman. Как говорят его создатели, это своего рода швейцарский нож, который позволяет формировать и выполнять запросы, документировать и мониторить сервисы в одном месте. Тестировщики могут писать тесты и производить автоматизированное тестирование прямо из Postman. 

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

Почему мы выбрали именно Cucumber и Spock?

В использовании SoapUI и Postman есть свои нюансы. Подобные тесты очень трудно поддерживать и проблематично использовать системы контроля версий (git, например) для их хранения.

Несмотря на то, что они широко используются в автоматизированном тестировании, SoapUI и Postman позволяют запускать тесты только локально и не могут применяться в системах интеграции (Jenkins). Для решения подобной задачи наша команда обратилась к Cucumber и Spock. С ними можно запускать тесты с Jenkins удаленно. Кроме того, эти фреймворки позволяют создавать автоматизированные смок-тесты, которые запускаются во время установки приложения. А вот с помощью Postman или SoapUI такое сделать не получится.

Spock и Cucumber отражают философию Behavior Driven Development — разработки через поведение. Идея BDD заключается в том, что перед тем, как написать какой-либо тест, необходимо сначала описать на предметно-ориентированном языке желаемый результат от добавляемой функциональности. После этого полученная документация передается разработчикам.

Спецификация поведения подается в полу формальном виде и имеет следующую структуру:

  • Заголовок (Title) — в сослагательной форме дается описание бизнес-цели.

  • Описание (Narrative) — в краткой форме даются ответы на следующие вопросы:

    • кто является заинтересованным лицом данной истории;

    • что входит в состав истории;

    • какую ценность эта история представляет для бизнеса.

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

Сценарий обычно строится по одной и той же схеме:

  • одно или несколько начальных условий (Given);

  • событие, которое инициирует начало этого сценария (When);

  • ожидаемый результат или результаты (Then).

BDD не предоставляет каких-либо формальных правил, но настаивает на том, чтобы использовался ограниченный стандартный набор фраз, включающий все элементы спецификации поведения. В 2007 году «отец» BDD Дэн Норт предложил шаблон для спецификации, который обрел широкую популярность и впоследствии стал известен, как язык Gherkin.

На сегодня один из самых популярных инструментов BDD — Cucumber. Его авторы стремились объединить автоматизированные приемочные испытания, функциональные требования и документацию ПО в единый формат, понятный и техническим, и нетехническим участникам проекта.

Основой описания сценария тестирования являются шаги Given, When, Then. Каждому из них соответствует аннотация, которая с помощью регулярного выражения связывает метод со строкой в текстовом описании сценария. Шаги тестирования группируются в сценарии (Scenario), которые в свою очередь описывают определенную функциональность (Feature).

Для автоматизации описанных сценариев в Cucumber можно использовать Ruby, Java и Python. Тест записывается в виде Gherkin-нотации в отдельный файл с расширением *.feature. Этот файл может содержать один или несколько сценариев. Сценарии могут писать BA или мануальные QA. Далее специалист, занимающийся автоматизацией тестов, создает отдельный класс с реализацией шагов на определенном языке программирования.

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

Feature: Test OpenWeather API 
             As a customer
             In order to check weather 
             I want to get my city name in response. 

             Scenario Outline: Check if city name is returned correctly 
             When Sent request to openweathermap for “<cityReq>”
             Then Check that 200 response code is returned 
             And Server returns correct city name “<cityResp>”

Examples 
| cityReq           | cityResp |
| “Kharkiv, UA”  | “Kharkiv” |
| “London, GB”  | “London” |

На примере выше представлена Gherkin-нотация сценария для тестирования открытого OpenWeather API приложения. Для примера я написал простой сценарий, который отправляет запрос с определенными параметрами на сервер приложения и затем проверяет ответ с этого сервера.

 public class Stepdefs {

      @when ( “Sent request to openweathermap for {cityReq} “ )
      public void sent_request_to_ openweathermap ( String cityReq) { 

             HTTP Builder http =  null; 
             try  { 
             http = new  HTTP Builder (testUrl);
             String [ ] actualCity = cityReq.split ( regex: “, “ ) ;

Здесь в коде представлен пример класса Stepsdef на языке Java. Каждый шаг из feature файла привязывается к его реализации в Stepsdef классе с помощью аннотации (@Given, @When, @Then и тд.) и текста шага из feature файла.

Чтобы получить максимальную отдачу от Cucumber, нужно следовать принципам BDD, потому что Cucumber — только активатор для BDD.

Spock — это тестовая среда. Некоторые даже сказали бы «язык, построенный на базе языка Groovy». К этому фреймворку я обратился уже на другом проекте, где выступал в роли автоматизатора. Как я писал ранее, в Cucumber сценарии выполнения и реализация каждой конструкции разделены. Это позволяет составить удобочитаемые сценарии, но занимает много времени. Поэтому такой подход может быть непрактичным при написании реализации.

Описание шагов и их реализация в Spock находятся в одном groovy классе. Благодаря использованию в качестве основы платформы JUnit, этот фреймворк совместим со всеми популярными IDE (в частности, IntelliJ IDEA), различными инструментами сборки (Ant, Gradle, Maven) и CI-сервисами (continuous integration). Тестовый класс являет собой набор методов-сценариев с названиями в кавычках, подобные названиям сценариев в Cucumber. А поскольку эти классы являются производными от JUnit, есть возможность запускать их из IDE как обычный модульный тест Groovy. При этом мы получаем стандартные JUnit отчеты, что очень удобно при разработке и отладке автоматизированных тестов.

В Spock каждая фаза теста выделена в отдельный блок кода, который начинается с лейбла и завершается началом следующего блока кода или окончанием теста. Блок Given отвечает за настройку начальных условий теста. В блоке When — стимулятор, раздражитель системы, а в блоке Then — ответная реакция системы. Оба блока всегда используются вместе. Если есть возможность сократить конструкцию When-Then до одного выражения, можно использовать один блок Expect.

class WeatherTestSpec extends Specification {
      @Shared def testUrl, testResponse 
       def setupSpec () {
       testUrl = “http:// api. openweathermap.org” 
       testRequest = [ ‘APPID’ : “aaa” ] 
       testResponse = ‘  ‘
}

def  ‘ Check if city name and coordinates is returned correctly’ () { 

when: ‘ Sent request to openweathermap’
def  http =  new HTTPBuilder(testUrl)
testRequest.put ( ‘q’, cityReq)
testResponse = http.get( path :   ‘/data/2.5/weather’ , query : testRequest )
then: “Check that 200 response code is returned”
testResponse. cod == 200

and:  “Server returns correct city name”
testResponse. name == cityResp 

where:  
cityReq << [  “Kharkiv, UA”” ,   “London, GB””  ] 
cityResp <<  [  “Kharkiv”” , “London ”  ] 

}

На примере выше представлен Groovy класс с тестом на Spock. Описание шага идет после символа «:» и представляет произвольную строку. При этом оно не является обязательным элементом. Spock допускает создание спецификации теста без описания шагов. Однако такая практика не считается общепринятой и в будущем приводит к затруднению понимания логики теста.

А что лучше?

И Cucumber, и Spock тесно связывают спецификацию на человеческом языке с тестовым кодом. Это прямое следствие парадигмы BDD, для поддержки которой создали обе платформы. Но Cucumber делает это более строго. Большие изменения описания шага на человеческом языке нарушат тестовый код, например, с отсутствующей реализацией шага, если ни одно регулярное выражение метода не соответствует заданному тексту шага. В то время как для Spock текст представляет собой произвольную строку после символа «:». Описание шага проверяется на соответствие в последующей реализации.

Cucumber четко разделяет спецификацию на человеческом языке и тестовым кодом. Для нетехнических специалистов, которые пишут или читают спецификации, это безусловно удобно. Да и сама суть BDD — это тесное сотрудничество Product Owner, BA, QA, архитекторов и разработчиков. Так что в случае с Cucumber спецификация будет согласована и понятна всем участникам проекта до начала разработки.

С другой стороны, Spock предлагает быстрое, краткое и однофайловое решение. Возможность Groovy использовать любую строку в качестве названия метода позволяет применять удобные для восприятия названия отдельного тестового сценария. Spock дает разработчикам единую точку для чтения и понимания спецификации и кода, который ее реализует. А еще давайте не забывать о «плюшках», с которыми поставляется Spock (например, расширенные возможности таблицы данных).

Также стоит отметить, что Cucumber подходит исключительно для интеграционных тестов. В то время, как Spock может использоваться и для Unit-тестов.

Было бы неправильно определять, какой из этих способов автоматизации тестирования API однозначно лучше. Мы в NIX, в зависимости от задач и целей, выбираем и то, и другое. SoapUI и Postman отлично подходят на начальных этапах автоматизации, когда в команде нет или очень мало автоматизаторов. С ростом команды логичнее переходить на Cucumber или Spock. У каждого из этих фреймворков есть свои преимущества, которые упрощают рутинные задачи QA-специалистов и делают процесс тестирования более эффективным.

Комментарии (1)


  1. Alekssh1ft
    15.11.2021 10:32

    Насколько я помню - коллекции постмана легко запускаются утилитой newman.