REST API Тестване с карате

1. Общ преглед

В тази статия ще представим Karate, рамка за тестване на поведенческо развитие (BDD) за Java.

2. Карате и BDD

Карате е изградено върху Cucumber , друга рамка за тестване на BDD, и споделя някои от същите концепции. Едно от тях е използването на файл с корнишон, който описва тестваната функция . Въпреки това, за разлика от Cucumber, тестовете не са написани на Java и са напълно описани във файла Gherkin.

Файлът от корнишони се записва с разширението “ .feature” . Започва с ключовата дума Feature , последвана от името на функцията на същия ред. Той също така съдържа различни тестови сценарии, всеки от които започва с ключовата дума Scenario и се състои от множество стъпки с ключовите думи Give , 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. Създаване на тестове

Ще започнем с написването на тестове за някои често срещани сценарии във файл с характеристики на корнишони .

4.1. Тестване на кода на състоянието

Нека напишем сценарий, който тества GET крайна точка и проверява дали връща 200 (OK) HTTP код на състоянието:

Scenario: Testing valid GET endpoint Given url '//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 '//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 '//localhost:8097/user/get' When method GET Then status 200 And match $ contains {id:"1234"}

4.3. Проверка на стойностите на отговора с маркери

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

Например можем да използваме маркер, за да посочим дали очакваме нулева стойност или не:

  • #нула
  • #notnull

Или можем да използваме маркер, за да съответства на определен тип стойност в поле:

  • #boolean
  • # номер
  • #string

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

  • # масив
  • # обект

And there're markers for matching on a certain format or regular expression and one that evaluates a boolean expression:

  • #uuid — value conforms to the UUID format
  • #regex STR — value matches the regular expression STR
  • #? EXPR — asserts that the JavaScript expression EXPR evaluates to true

Finally, if we don't want any kind of check on a field, we can use the #ignore marker.

Let's rewrite the above scenario to check that the id field is not null:

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

4.4. Testing a POST Endpoint With a Request Body

Let's look at a final scenario that tests a POST endpoint and takes a request body:

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

5. Running Tests

Now that the test scenarios are complete, we can run our tests by integrating Karate with JUnit.

We'll use the @CucumberOptions annotation to specify the exact location of the Feature files:

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

To demonstrate the REST API, we'll use a WireMock server.

For this example, we mock all the endpoints that are being tested in the method annotated with @BeforeClass. We'll shut down the WireMock server in the method annotated with @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(); }

When we run the KarateUnitTest class, the REST Endpoints are created by the WireMock Server, and all the scenarios in the specified feature file are run.

6. Conclusion

In this tutorial, we looked at how to test REST APIs using the Karate Testing Framework.

Пълният изходен код и всички кодови фрагменти за тази статия могат да бъдат намерени в GitHub.