1. Обзор
В этой статье мы представим Karate , платформу тестирования поведенческой разработки (BDD) для Java.
2. Каратэ и БДД
Каратэ построен поверх Cucumber , другого BDD-тестирования фреймворка, и разделяет некоторые из тех же концепций. Одним из них является использование файла корнишона, который описывает тестируемую функцию . Однако, в отличие от Cucumber, тесты не написаны на Java и полностью описаны в файле Gherkin.
Файл корнишона сохраняется с расширением ” .feature” . Он начинается с ключевого слова Feature , за которым следует имя функции в той же строке. Он также содержит различные тестовые сценарии, каждый из которых начинается с ключевого слова Scenario и состоит из нескольких шагов с ключевыми словами Given , When , Then , And , и But .
Подробнее об огурцах и структуре корнишонов можно узнать здесь .
3. Зависимости Maven
Чтобы использовать каратэ в проекте 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. Создание тестов
Мы начнем с написания тестов для некоторых распространенных сценариев в файле Gherkin Feature .
4.1. Проверка кода состояния
Давайте напишем сценарий, который проверяет конечную точку GET и проверяет, возвращает ли она 200 (ОК) Код состояния HTTP:
Scenario: Testing valid GET endpoint Given url 'http://localhost:8097/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:8097/user/get' When method GET Then status 200 And match $ == {id:"1234",name:"John Smith"}
Операция match используется для проверки , где ‘ $’ представляет ответ. Таким образом,приведенный выше сценарий проверяет, что ответ точно соответствует” {id:”1234″, имя:”Джон Смит”}”.
Мы также можем специально проверить значение поля id :
And match $.id == "1234"
Операция match также может использоваться для проверки того, содержит ли ответ определенные поля. Это полезно, когда необходимо проверить только определенные поля или когда известны не все поля ответа:
Scenario: Testing that GET response contains specific field Given url 'http://localhost:8097/user/get' When method GET Then status 200 And match $ contains {id:"1234"}
4.3. Проверка Значений Ответов С Помощью Маркеров
В случае, когда мы не знаем точного возвращаемого значения, мы все равно можем проверить значение, используя маркеры — заполнители для соответствующих полей в ответе.
Например, мы можем использовать маркер, чтобы указать, ожидаем ли мы значение null или нет:
- #null
- #notnull
Или мы можем использовать маркер для сопоставления определенного типа значения в поле:
- #логическое значение
- #номер
- #строка
Другие маркеры доступны для тех случаев, когда мы ожидаем, что поле будет содержать объект или массив JSON:
- #массив
- #объект
И есть маркеры для сопоставления в определенном формате или регулярном выражении и один, который вычисляет логическое выражение:
- #uuid — значение соответствует формату UUID
- #регулярное выражение STR — значение соответствует регулярному выражению STR
- #? EXPR — утверждает, что выражение JavaScript EXPR имеет значение true
Наконец, если нам не нужна какая-либо проверка поля, мы можем использовать маркер #ignore .
Давайте перепишем приведенный выше сценарий, чтобы проверить, что поле id не является null :
Scenario: Test GET request exact response Given url 'http://localhost:8097/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:8097/user/create' And request { id: '1234' , name: 'John Smith'} When method POST Then status 200 And match $ contains {id:"#notnull"}
5. Выполнение тестов
Теперь, когда тестовые сценарии завершены, мы можем запустить наши тесты, интегрировав Каратэ с JUnit.
Мы будем использовать аннотацию @CucumberOptions , чтобы указать точное местоположение файлов Feature :
@RunWith(Karate.class) @CucumberOptions(features = "classpath:karate") public class KarateUnitTest { //... }
Чтобы продемонстрировать REST API, мы будем использовать сервер WireMock.
В этом примере мы имитируем все конечные точки, которые тестируются в методе с аннотацией @BeforeClass . Мы отключим сервер WireMock в методе с аннотацией @AfterClass :
private static WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.options().port(8097)); @BeforeClass public static void setUp() throws Exception { wireMockServer.start(); configureFor("localhost", 8097); 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 , остальные конечные точки создаются сервером WireMock, и запускаются все сценарии в указанном файле функций.
6. Заключение
В этом уроке мы рассмотрели, как тестировать API REST с помощью платформы тестирования Karate.
Полный исходный код и все фрагменты кода для этой статьи можно найти на GitHub .