Тестирование API REST с каратэ

Тестирование API REST с каратэ

1. обзор

В этой статье мы познакомим вас сKarate, фреймворком для тестирования Java, управляемой поведением (Behavior Driven Development, BDD).

2. Каратэ и BDD

Karate isbuilt on top of Cucumber, еще одна среда тестирования BDD, которая разделяет некоторые из тех же концепций. Один из них -the use of a Gherkin file, which describes the tested feature. Однако, в отличие от Cucumber, тесты не написаны на Java и полностью описаны в файле Gherkin.

Файл Gherkin сохраняется с расширением «.feature”. Он начинается с ключевого словаFeature, за которым следует имя функции в той же строке. Он также содержит различные тестовые сценарии, каждый из которых начинается с ключевого словаScenario и состоит из нескольких шагов с ключевыми словамиGiven,When,Then,And и But.

Подробнее об огурце и структуре корнишона можно найти вhere.

3. Maven Зависимости

Чтобы использовать Karate в проекте Maven, нам нужно добавить зависимостьkarate-apache кpom.xml:


    com.intuit.karate
    karate-apache
    0.6.0

Нам также понадобится зависимостьkarate-junit4 для облегчения тестирования JUnit:


    com.intuit.karate
    karate-junit4
    0.6.0

4. Создание тестов

Мы начнем с написания тестов для некоторых распространенных сценариев в файле GherkinFeature.

4.1. Проверка кода состояния

Давайте напишем сценарий, который проверяет конечную точку GET и проверяет, возвращает ли она код состояния HTTP200 (OK):

Scenario: Testing valid GET endpoint
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200

Это работает, очевидно, со всеми возможными кодами состояния HTTP.

4.2. Проверка ответа

Давайте напишем еще один сценарий, который проверяет, что конечная точка REST возвращает определенный ответ:

Scenario: Testing the exact response of a GET endpoint
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200
And match $ == {id:"1234",name:"John Smith"}

The match operation is used for the validation, где ‘$' представляет собой ответ. Таким образом, в приведенном выше сценарии проверяется, что ответ в точности соответствует "\{id:”1234″,name:”John Smith”}'.

Мы также можем специально проверить значение поляid:

And match $.id == "1234"

The match operation can also be used to check if the response contains certain fields. Это полезно, когда нужно проверить только определенные поля или когда известны не все поля ответа:

Scenario: Testing that GET response contains specific field
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200
And match $ contains {id:"1234"}

4.3. Проверка значений ответа с помощью маркеров

В случае, если мы не знаем точного возвращаемого значения, мы все равно можем проверить значение, используяmarkers - заполнители для сопоставления полей в ответе.

Например, мы можем использовать маркер, чтобы указать, ожидаем ли мы значенияnull или нет:

  • #null

  • #notnull

Или мы можем использовать маркер, чтобы соответствовать определенному типу значения в поле:

  • #boolean

  • #number

  • #string

Другие маркеры доступны, когда мы ожидаем, что поле будет содержать объект или массив JSON:

  • #array

  • #object

И есть маркеры для сопоставления в определенном формате или регулярном выражении и маркеры, оценивающие логическое выражение:

  • Значение#uuid — соответствует формату UUID

  • Значение#regex STR — соответствует регулярному выражениюSTR

  • #? EXPR — утверждает, что выражение JavaScriptEXPR оценивается какtrue

Наконец, если нам не нужна какая-либо проверка поля, мы можем использовать маркер#ignore.

Давайте перепишем приведенный выше сценарий, чтобы убедиться, что полеid не являетсяnull:

Scenario: Test GET request exact response
Given url 'http://localhost:8080/user/get'
When method GET
Then status 200
And match $ == {id:"#notnull",name:"John Smith"}

4.4. Тестирование конечной точки POST с телом запроса

Давайте посмотрим на последний сценарий, который тестирует конечную точку POST и принимает тело запроса:

Scenario: Testing a POST endpoint with request body
Given url 'http://localhost:8080/user/create'
And request { id: '1234' , name: 'John Smith'}
When method POST
Then status 200
And match $ contains {id:"#notnull"}

5. Запуск тестов

Теперь, когда тестовые сценарии завершены, мы можем запустить наши тесты, интегрировав Karate с JUnit.

Мы будем использовать аннотацию@CucumberOptions, чтобы указать точное местоположение файловFeature:

@RunWith(Karate.class)
@CucumberOptions(features = "classpath:karate")
public class KarateUnitTest {
//...
}

Чтобы продемонстрировать REST API, мы будем использоватьWireMock server.

В этом примере мы имитируем все конечные точки, которые тестируются в методе, помеченном@BeforeClass. Мы отключим сервер WireMock с помощью метода, помеченного@AfterClass:

private static WireMockServer wireMockServer
  = new WireMockServer();

@BeforeClass
public static void setUp() throws Exception {
    wireMockServer.start();
    configureFor("localhost", 8080);
    stubFor(
      get(urlEqualTo("/user/get"))
        .willReturn(aResponse()
          .withStatus(200)
          .withHeader("Content-Type", "application/json")
          .withBody("{ \"id\": \"1234\", name: \"John Smith\" }")));

    stubFor(
      post(urlEqualTo("/user/create"))
        .withHeader("content-type", equalTo("application/json"))
        .withRequestBody(containing("id"))
        .willReturn(aResponse()
          .withStatus(200)
          .withHeader("Content-Type", "application/json")
          .withBody("{ \"id\": \"1234\", name: \"John Smith\" }")));

}

@AfterClass
public static void tearDown() throws Exception {
    wireMockServer.stop();
}

Когда мы запускаем классKarateUnitTest, конечные точки REST создаются сервером WireMock, и выполняются все сценарии в указанном файле функций.

6. Заключение

В этом уроке мы рассмотрели, как тестировать API REST с использованием инфраструктуры тестирования каратэ.

Полный исходный код и все фрагменты кода для этой статьи можно найтиover on GitHub.