«1. Обзор
В этой статье мы познакомим вас с Karate, средой тестирования Behavior Driven Development (BDD) для Java.
2. Karate и BDD
Karate построен на основе Cucumber, другой среды тестирования BDD, и использует некоторые из тех же концепций. Одним из них является использование файла Gherkin, в котором описывается тестируемая функция. Однако, в отличие от Cucumber, тесты написаны не на Java и полностью описаны в файле Gherkin.
Файл корнишона сохраняется с расширением «.feature». Он начинается с ключевого слова Feature, за которым следует имя функции в той же строке. Он также содержит различные тестовые сценарии, каждый из которых начинается с ключевого слова «Сценарий» и состоит из нескольких шагов с ключевыми словами «Дано», «Когда», «Тогда», «И» и «Но».
Подробнее о Cucumber и структуре Gherkin можно узнать здесь.
3. Зависимости Maven
Чтобы использовать Karate в проекте Maven, нам нужно добавить зависимость karate-apache в pom.xml:
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-apache</artifactId>
<version>0.6.0</version>
</dependency>
Нам также понадобится karate-junit4 зависимость для облегчения тестирования JUnit:
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-junit4</artifactId>
<version>0.6.0</version>
</dependency>
4. Создание тестов
Мы начнем с написания тестов для некоторых распространенных сценариев в файле Gherkin Feature.
4.1. Тестирование кода состояния
Давайте напишем сценарий, который тестирует конечную точку GET и проверяет, возвращает ли она код состояния HTTP 200 (ОК):
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"}
Операция сопоставления используется для проверки, где «$» представляет ответ. Таким образом, приведенный выше сценарий проверяет, что ответ точно соответствует «{id:» 1234», name: «John Smith»}.
Мы также можем специально проверить значение поля id:
And match $.id == "1234"
Операция сопоставления также может использоваться для проверки того, содержит ли ответ определенные поля. Это полезно, когда нужно проверить только определенные поля или когда известны не все поля ответа:
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 #notnull
Или мы можем использовать маркер, чтобы соответствовать определенному типу значения в поле: ~ ~~ #boolean #number #string
-
Другие маркеры доступны, когда мы ожидаем, что поле будет содержать объект JSON или массив:
#array #object
-
И есть маркеры для сопоставления в определенном формате или регулярное выражение и вычисляющее логическое выражение:
#uuid — значение соответствует формату UUID #regex STR — значение соответствует регулярному выражению STR #? EXPR — утверждает, что выражение JavaScript EXPR оценивается как истинное
-
Наконец, если мы не хотим какой-либо проверки поля, мы можем использовать маркер #ignore.
Давайте перепишем приведенный выше сценарий, чтобы проверить, что поле id не пустое:
4.4. Тестирование конечной точки POST с телом запроса
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"}
Давайте рассмотрим окончательный сценарий, который проверяет конечную точку POST и принимает тело запроса:
5. Запуск тестов
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"}
Теперь, когда тестовые сценарии завершены, мы можно запустить наши тесты, интегрировав Karate с JUnit.
Мы будем использовать аннотацию @CucumberOptions, чтобы указать точное расположение файлов функций:
Чтобы продемонстрировать REST API, мы будем использовать сервер WireMock.
@RunWith(Karate.class)
@CucumberOptions(features = "classpath:karate")
public class KarateUnitTest {
//...
}
В этом примере мы имитируем все конечные точки, которые тестируются в методе, аннотированном @BeforeClass. Мы выключим сервер WireMock в методе, аннотированном @AfterClass:
Когда мы запускаем класс KarateUnitTest, конечные точки REST создаются сервером WireMock, и все сценарии в указанном файле функций запускаются. .
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();
}
6. Заключение
В этом руководстве мы рассмотрели, как тестировать REST API с помощью Karate Testing Framework.
Полный исходный код и все фрагменты кода для этой статьи можно найти на GitHub.
«