Библиотека для тестирования JSON-RPC API

от автора

Когда я впервые столкнулся с написанием тестов для микросервиса, API которого был реализован согласно протоколу JSON-RPC, я осознал что построение качественных проверок для json элементов куда требовательнее, чем я считал ранее.

Ниже приведён простой пример.

От сервиса получен ответ:

{   "result": 12,   "id": 46929734,   "jsonrpc": "2.0" }

Что требуется проверить:

  1. Ответ содержит элемент «jsonrpc» и его значение равняется «2.0»
  2. Ответ содержит элемент «id» и его значение равняется аналогичному элементу переданному в запросе, в данный момент допустим это — 46929734

Ответ содержит элемент «result» и его значение равняется 12


Как это необходимо проверить, используя Java + TestNG + Gson:

Assert.assertTrue(response.has("result")); Assert.assertTrue(response.has("jsonrpc")); Assert.assertTrue(response.has("id"));  Assert.assertTrue(response.get("result").isJsonPrimitive()); Assert.assertTrue(response.get("jsonrpc").isJsonPrimitive()); Assert.assertTrue(response.get("id").isJsonPrimitive());  Assert.assertEquals(response.get("result").getAsInt(), 12); Assert.assertEquals(response.get("jsonrpc").getAsString(), "2.0"); Assert.assertEquals(response.get("id").getAsInt(), 46929734);

В этот момент, в сознании может начать формироваться вопрос «Зачем так много ассертов?». Да, фактически при тестировании, вас интересует только группа из трех последних ассертов, они проверяют значения json элементов в ответе и если они пройдут — значит ответ соответствует ожиданиям. Но, что если тест упадет? Рассмотрим несколько возможных причин падения такого теста:

  1. Ответ ->
    {   "result": 12,   "id": 46929734,   "jsonrpc": "1.0" }

    Ошибка от TestNG -> java.lang.AssertionError: expected [2.0] but found [1.0]
    Ждали «2.0», получили «1.0» — тут все понятно.

  2. Ответ ->
    {   "result": 12,   "id": 46929734,   "jsonrpc": {} }

    Ошибка от TestNG -> java.lang.UnsupportedOperationException: JsonObject

    Попытались распарсить как строку элемент, который абсолютно неожиданно получили в ответе как обьект.

  3. Ответ ->
    {   "result": 12,   "id": 46929734 }

    Ошибка от TestNG -> java.lang.NullPointerException
    Попытались распарсить как строку элемент, которого нет в ответе.

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

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

Gassert.verifyInteger(response, "result", 12); Gassert.verifyString(response, "jsonrpc", "2.0"); Gassert.verifyInteger(response, "id", 46929734); 

В библиотеке реализованы методы для проверки:

  • элементов всех примитивных типов, вложенных и нет, с проверкой значения и без
  • JsonObject, вложенных и нет, с проверкой значения и без
  • JsonArray, вложенных и нет, с проверкой значения и без
  • JsonNull элементов, вложенных и нет
  • типов элементов внутри массива
  • содержания массивом ожидаемого элемента
  • размерности массива
  • размерности обьекта

На всех уровнях проверки, реализованы более детализированные ошибки относительно тех что предоставляет TestNG по умолчанию.

Рассмотрим повторно возможные причины падения теста:

  1. Ответ ->
     {   "result": 12,   "id": 46929734,   "jsonrpc": "1.0" } 

    Ошибка от Gassert -> java.lang.AssertionError: Element [jsonrpc] verification failed. expected [2.0] but found [1.0]

  2. Ответ ->
     {   "result": 12,   "id": 46929734,   "jsonrpc": {} } 

    Ошибка от Gassert -> java.lang.AssertionError: Element [jsonrpc] is not a JsonPrimitive. did not expect to find [true] but found [false]

  3. Ответ ->
     {   "result": 12,   "id": 46929734 } 

    Ошибка от Gassert -> java.lang.AssertionError: Json does not contains element: [jsonrpc]. did not expect to find [true] but found [false]

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

Библиотека находится в публичном github репозитории, а также добавлена в maven репозиторий.

Maven
Github
APIDocs


ссылка на оригинал статьи https://habr.com/ru/post/480976/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *