Как стать автором
Обновить

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

Время на прочтение4 мин
Количество просмотров4.8K
Когда я впервые столкнулся с написанием тестов для микросервиса, 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
Теги:
Хабы:
Всего голосов 4: ↑4 и ↓0+4
Комментарии3

Публикации

Истории

Работа

Ближайшие события

One day offer от ВСК
Дата16 – 17 мая
Время09:00 – 18:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург