Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:
>> ПРЕГЛЕД НА КУРСА1. Въведение
REST-assured е проектиран да опрости тестването и валидирането на REST API и е силно повлиян от техниките за тестване, използвани в динамични езици като Ruby и Groovy.
Библиотеката има солидна поддръжка за HTTP, като се започне разбира се с глаголите и стандартните HTTP операции, но също така надхвърля тези основи.
В това ръководство ще проучим REST-уверено и ще използваме Hamcrest, за да направим твърдение. Ако все още не сте запознати с Hamcrest, първо трябва да се справите с урока: Тестване с Hamcrest.
Също така, за да научите за по-напредналите случаи на използване на REST-гарантирано, разгледайте другите ни статии:
- ОТСТАНОВЕНО с Groovy
- JSON схема за проверка с REST-гарантирано
- Параметри, заглавки и бисквитки с REST-гарантирано
Сега нека се потопим с прост пример.
2. Прост примерен тест
Преди да започнем, нека се уверим, че нашите тестове имат следното статично импортиране:
io.restassured.RestAssured.* io.restassured.matcher.RestAssuredMatchers.* org.hamcrest.Matchers.*
Това ще ни е необходимо, за да улесним тестовете и да имаме лесен достъп до основните API.
Сега нека да започнем с простия пример - основна система за залагане, излагаща някои данни за игри:
{ "id": "390", "data": { "leagueId": 35, "homeTeam": "Norway", "visitingTeam": "England", }, "odds": [{ "price": "1.30", "name": "1" }, { "price": "5.25", "name": "X" }] }
Да кажем, че това е JSON отговорът от удряне на локално разположен API - // localhost: 8080 / events? Id = 390. :
Нека сега използваме REST-уверено, за да проверим някои интересни характеристики на отговора JSON:
@Test public void givenUrl_whenSuccessOnGetsResponseAndJsonHasRequiredKV_thenCorrect() { get("/events?id=390").then().statusCode(200).assertThat() .body("data.leagueId", equalTo(35)); }
И така, това, което направихме тук, е - проверихме, че извикване на крайна точка / събития? Id = 390 отговаря с тяло, съдържащо JSON String, чийто leagueId на обекта на данни е 35.
Нека да разгледаме по-интересен пример. Да предположим, че искате да проверите дали масивът с коефициенти има записи с цени 1.30 и 5.25 :
@Test public void givenUrl_whenJsonResponseHasArrayWithGivenValuesUnderKey_thenCorrect() { get("/events?id=390").then().assertThat() .body("odds.price", hasItems("1.30", "5.25")); }
3. REST-гарантирана настройка
Ако вашият любим инструмент за зависимост е Maven, ние добавяме следната зависимост във файла pom.xml :
io.rest-assured rest-assured 3.3.0 test
За да получите най-новата версия, следвайте тази връзка.
REST-assured се възползва от силата на мачовете на Hamcrest, за да изпълни своите твърдения, така че трябва да включим и тази зависимост:
org.hamcrest hamcrest-all 2.1
Най-новата версия винаги ще бъде достъпна на тази връзка.
4. Анонимно валидиране на JSON Root
Помислете за масив, който се състои от примитиви, а не от обекти:
[1, 2, 3]
Това се нарича анонимен JSON корен, което означава, че той няма двойка ключ-стойност, въпреки че все още е валиден JSON данни.
Можем да стартираме проверка в такъв сценарий, като използваме $
символа или празен низ („”) като път. Да приемем, че излагаме горната услуга чрез // localhost: 8080 / json, след което можем да я проверим така с REST-уверено:
when().get("/json").then().body("$", hasItems(1, 2, 3));
или по този начин:
when().get("/json").then().body("", hasItems(1, 2, 3));
5. Плувки и двойки
Когато започнем да използваме REST-гарантирано за тестване на нашите REST услуги, трябва да разберем, че числата с плаваща запетая в отговорите на JSON се преобразуват в примитивен тип float.
Използването на тип float не е взаимозаменяемо с double, както е при много сценарии в java.
Пример за това е този отговор:
{ "odd": { "price": "1.30", "ck": 12.2, "name": "1" } }
да предположим, че провеждаме следния тест за стойността на ck :
get("/odd").then().assertThat().body("odd.ck", equalTo(12.2));
Този тест ще се провали, дори ако стойността, която тестваме, е равна на стойността в отговора. Това е така, защото сравняваме с двойно, а не с плувка .
За да работи, трябва изрично да посочим операнда на метода equTo matcher като плувка , по следния начин:
get("/odd").then().assertThat().body("odd.ck", equalTo(12.2f));
6. Посочване на метода на заявката
Обикновено бихме изпълнили заявка, като извикаме метод като get (), съответстващ на метода на заявката, който искаме да използваме.
В допълнение, ние също може да укажете HTTP глагол с помощта на заявка () метода :
@Test public void whenRequestGet_thenOK(){ when().request("GET", "/users/eugenp").then().statusCode(200); }
Примерът по-горе е еквивалентен на използването на get () директно.
По същия начин можем да изпращаме заявки HEAD , CONNECT и OPTIONS :
@Test public void whenRequestHead_thenOK() { when().request("HEAD", "/users/eugenp").then().statusCode(200); }
POST request also follows a similar syntax and we can specify the body by using the with() and body() methods.
Therefore, to create a new Odd by sending a POST request:
@Test public void whenRequestedPost_thenCreated() { with().body(new Odd(5.25f, 1, 13.1f, "X")) .when() .request("POST", "/odds/new") .then() .statusCode(201); }
The Odd object sent as body will automatically be converted to JSON. We can also pass any String that we want to send as our POSTbody.
7. Default Values Configuration
We can configure a lot of default values for the tests:
@Before public void setup() { RestAssured.baseURI = "//api.github.com"; RestAssured.port = 443; }
Here, we're setting a base URI and port for our requests. Besides these, we can also configure the base path, root pat, and authentication.
Note: we can also reset to the standard REST-assured defaults by using:
RestAssured.reset();
8. Measure Response Time
Let's see how we can measure the response time using the time() and timeIn() methods of the Response object:
@Test public void whenMeasureResponseTime_thenOK() { Response response = RestAssured.get("/users/eugenp"); long timeInMS = response.time(); long timeInS = response.timeIn(TimeUnit.SECONDS); assertEquals(timeInS, timeInMS/1000); }
Note that:
- time() is used to get response time in milliseconds
- timeIn() is used to get response time in the specified time unit
8.1. Validate Response Time
We can also validate the response time – in milliseconds – with the help of simple longMatcher:
@Test public void whenValidateResponseTime_thenSuccess() { when().get("/users/eugenp").then().time(lessThan(5000L)); }
If we want to validate the response time in a different time unit, then we'll use the time() matcher with a second TimeUnit parameter:
@Test public void whenValidateResponseTimeInSeconds_thenSuccess(){ when().get("/users/eugenp").then().time(lessThan(5L),TimeUnit.SECONDS); }
9. XML Response Verification
Not only can it validate a JSON response, itcan validate XML as well.
Let's assume we make a request to //localhost:8080/employees and we get the following response:
Jane Daisy f
We can verify that the first-name is Jane like so:
@Test public void givenUrl_whenXmlResponseValueTestsEqual_thenCorrect() { post("/employees").then().assertThat() .body("employees.employee.first-name", equalTo("Jane")); }
We can also verify that all values match our expected values by chaining body matchers together like so:
@Test public void givenUrl_whenMultipleXmlValuesTestEqual_thenCorrect() { post("/employees").then().assertThat() .body("employees.employee.first-name", equalTo("Jane")) .body("employees.employee.last-name", equalTo("Daisy")) .body("employees.employee.sex", equalTo("f")); }
Or using the shorthand version with variable arguments:
@Test public void givenUrl_whenMultipleXmlValuesTestEqualInShortHand_thenCorrect() { post("/employees") .then().assertThat().body("employees.employee.first-name", equalTo("Jane"),"employees.employee.last-name", equalTo("Daisy"), "employees.employee.sex", equalTo("f")); }
10. XPath for XML
We can also verify our responses using XPath. Consider the example below that executes a matcher on the first-name:
@Test public void givenUrl_whenValidatesXmlUsingXpath_thenCorrect() { post("/employees").then().assertThat(). body(hasXPath("/employees/employee/first-name", containsString("Ja"))); }
XPath also accepts an alternate way of running the equalTo matcher:
@Test public void givenUrl_whenValidatesXmlUsingXpath2_thenCorrect() { post("/employees").then().assertThat() .body(hasXPath("/employees/employee/first-name[text()='Jane']")); }
11. Logging Test Details
11.1. Log Request Details
First, let's see how to log entire request details using log().all():
@Test public void whenLogRequest_thenOK() { given().log().all() .when().get("/users/eugenp") .then().statusCode(200); }
This will log something like this:
Request method: GET Request URI: //api.github.com:443/users/eugenp Proxy: Request params: Query params: Form params: Path params: Multiparts: Headers: Accept=*/* Cookies: Body:
To log only specific parts of the request, we have the log() method in combination with params(), body(), headers(), cookies(), method(), path() eg log.().params().
Note that other libraries or filters used may alter what's actually sent to the server, so this should only be used to log the initial request specification.
11.2. Log Response Details
Similarly, we can log the response details.
In the following example we're logging the response body only:
@Test public void whenLogResponse_thenOK() { when().get("/repos/eugenp/tutorials") .then().log().body().statusCode(200); }
Sample output:
{ "id": 9754983, "name": "tutorials", "full_name": "eugenp/tutorials", "private": false, "html_url": "//github.com/eugenp/tutorials", "description": "The \"REST With Spring\" Course: ", "fork": false, "size": 72371, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "//api.github.com/licenses/mit" }, ... }
11.3. Log Response if Condition Occurred
We also have the option of logging the response only if an error occurred or the status code matches a given value:
@Test public void whenLogResponseIfErrorOccurred_thenSuccess() { when().get("/users/eugenp") .then().log().ifError(); when().get("/users/eugenp") .then().log().ifStatusCodeIsEqualTo(500); when().get("/users/eugenp") .then().log().ifStatusCodeMatches(greaterThan(200)); }
11.4. Log if Validation Failed
We can also log both request and response only if our validation failed:
@Test public void whenLogOnlyIfValidationFailed_thenSuccess() { when().get("/users/eugenp") .then().log().ifValidationFails().statusCode(200); given().log().ifValidationFails() .when().get("/users/eugenp") .then().statusCode(200); }
В този пример искаме да потвърдим, че кодът на състоянието е 200. Само ако това не успее, заявката и отговорът ще бъдат регистрирани.
12. Заключение
В този урок проучихме REST-уверената рамка и разгледахме най-важните й характеристики, които можем да използваме, за да тестваме нашите RESTful услуги и да потвърдим техните отговори.
Пълното изпълнение на всички тези примери и кодови фрагменти може да се намери в RIT-гарантирания проект GitHub.
Джаксън отдолу