En guide til REST-forsikret

Jackson Top

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

1. Introduksjon

REST-forsikret ble designet for å forenkle testing og validering av REST APIer og er sterkt påvirket av testteknikker som brukes i dynamiske språk som Ruby og Groovy.

Biblioteket har solid støtte for HTTP, og starter selvfølgelig med verbene og standard HTTP-operasjoner, men går også langt utover disse grunnleggende.

I denne guiden skal vi utforske REST-forsikret og vi skal bruke Hamcrest til å gjøre påstander. Hvis du ikke allerede er kjent med Hamcrest, bør du først pusse opp med veiledningen: Testing with Hamcrest.

For å lære om mer avanserte bruksområder for REST-forsikret, sjekk ut våre andre artikler:

  • HVILE-forsikret med Groovy
  • JSON Schema Validation with REST-assured
  • Parametere, overskrifter og informasjonskapsler med REST-forsikret

La oss nå dykke inn med et enkelt eksempel.

2. Enkel eksempletest

Før vi begynner, la oss forsikre oss om at testene våre har følgende statiske import:

io.restassured.RestAssured. * io.restassured.matcher.RestAssuredMatchers. * org.hamcrest.Matchers. *

Vi trenger det for å holde testene enkle og få enkel tilgang til de viktigste API-ene.

La oss komme i gang med det enkle eksemplet - et grunnleggende spillsystem som avslører data for spill:

{"id": "390", "data": {"leagueId": 35, "homeTeam": "Norway", "visitingTeam": "England",}, "odds": [{"price": "1.30 "," name ":" 1 "}, {" price ":" 5.25 "," name ":" X "}]}

La oss si at dette er JSON-svaret fra å treffe lokalt distribuert API - // localhost: 8080 / events? id = 390. :

La oss nå bruke REST-forsikret for å verifisere noen interessante funksjoner i svaret JSON:

@Test offentlig ugyldig gittUrl_whenSuccessOnGetsResponseAndJsonHasRequiredKV_thenCorrect () {get ("/ events? Id = 390"). Deretter (). StatusCode (200) .assertThat () .body ("data.leagueId", equalTo (35)); }

Så det vi gjorde her er - vi bekreftet at et kall til endepunktet / hendelser? id = 390 svarer med et legeme som inneholder en JSON String hvem sin leagueId av data objektet er 35.

La oss ta en titt på et mer interessant eksempel. La oss si at du vil bekrefte at odds array har poster med priser 1.30 og 5.25:

@Test offentlig ugyldig gittUrl_whenJsonResponseHasArrayWithGivenValuesUnderKey_thenCorrect () {get ("/ events? Id = 390"). Deretter (). AssertThat () .body ("odds.price", hasItems ("1.30", "5.25")); }

3. REST-sikret oppsett

Hvis ditt favorittavhengighetsverktøy er Maven, legger vi til følgende avhengighet i pom.xml fil:

 io.rest-forsikret rest -ured 3.3.0 test 

For å få den nyeste versjonen, følg denne lenken.

REST-forsikret utnytter kraften fra Hamcrest-matchere til å utføre sine påstander, så vi må også inkludere den avhengigheten:

 org.hamcrest hamcrest-all 2.1 

Den siste versjonen vil alltid være tilgjengelig på denne lenken.

4. Anonym JSON rotvalidering

Tenk på en matrise som består av primitive i stedet for objekter:

[1, 2, 3]

Dette kalles en anonym JSON-rot, noe som betyr at den ikke har noe nøkkelverdipar, men det er fortsatt gyldige JSON-data.

Vi kan kjøre validering i et slikt scenario ved å bruke $ symbol eller en tom streng (“”) som bane. Anta at vi utsetter tjenesten ovenfor gjennom // localhost: 8080 / json så kan vi validere det slik med REST-forsikret:

når (). get ("/ json"). deretter (). body ("$", hasItems (1, 2, 3));

eller slik:

når (). get ("/ json"). deretter (). body ("", hasItems (1, 2, 3));

5. Flyter og dobler

Når vi begynner å bruke REST-forsikret for å teste REST-tjenestene våre, må vi forstå at flytende tall i JSON-svar blir kartlagt til primitiv type flyte.

Bruken av flyte typen kan ikke byttes ut med dobbelt som tilfellet er for mange scenarier i java.

Eksempel på dette svaret:

{"odd": {"price": "1.30", "ck": 12.2, "name": "1"}}

antar at vi kjører følgende test på verdien av ck:

get ("/ odd"). deretter (). assertThat (). body ("odd.ck", equalTo (12.2));

Denne testen mislykkes selv om verdien vi tester er lik verdien i svaret. Dette er fordi vi sammenligner med a dobbelt snarere enn til en flyte.

For å få det til å fungere, må vi eksplisitt spesifisere operanden til lik matcher metode som en flyte, som så:

get ("/ odd"). deretter (). assertThat (). body ("odd.ck", equalTo (12.2f));

6. Spesifisere forespørselsmetoden

Vanligvis vil vi utføre en forespørsel ved å ringe en metode som få(), tilsvarer forespørselsmetoden vi vil bruke.

I tillegg, Vi kan også spesifisere HTTP-verbet ved hjelp av be om() metode:

@Test offentlig ugyldig nårRequestGet_thenOK () {når (). Forespørsel ("GET", "/users/eugenp").then().statusCode(200); }

Eksemplet ovenfor tilsvarer bruk få() direkte.

På samme måte kan vi sende HODE, KOBLE og ALTERNATIVER forespørsler:

@Test offentlig ugyldig nårRequestHead_thenOK () {når (). Forespørsel ("HEAD", "/users/eugenp").then().statusCode(200); }

POST forespørsel følger også en lignende syntaks, og vi kan spesifisere kroppen ved å bruke med() og kropp() metoder.

Derfor å skape et nytt Merkelig ved å sende en POST be om:

@Test offentlig ugyldig nårRequestedPost_thenCreated () {with (). Body (new Odd (5.25f, 1, 13.1f, "X")) .when () .request ("POST", "/ odds / new") .then () .statusCode (201); }

De Merkelig objekt sendt som kropp blir automatisk konvertert til JSON. Vi kan også passere alle String som vi ønsker å sende som vår POSTkropp.

7. Standardverdikonfigurasjon

Vi kan konfigurere mange standardverdier for testene:

@Før offentlige ugyldige oppsett () {RestAssured.baseURI = "//api.github.com"; RestAssured.port = 443; }

Her setter vi en grunnleggende URI og port for våre forespørsler. I tillegg til disse kan vi også konfigurere basestien, rotpat og autentisering.

Merk: Vi kan også tilbakestille til standard REST-sikre standarder ved å bruke:

RestAssured.reset ();

8. Mål responstid

La oss se hvordan vi kan måle responstiden ved hjelp av tid() og timeIn () metoder for Respons gjenstand:

@Test offentlig ugyldig nårMeasureResponseTime_thenOK () {Response response = RestAssured.get ("/ users / eugenp"); lang timeInMS = respons.tid (); lang timeInS = respons.timeIn (TimeUnit.SECONDS); assertEquals (timeInS, timeInMS / 1000); }

Noter det:

  • tid() brukes til å få responstid i millisekunder
  • timeIn () brukes til å få responstid i den angitte tidsenheten

8.1. Valider svartiden

Vi kan også validere responstiden - i millisekunder - ved hjelp av enkel langMatcher:

@Test offentlig ugyldig nårValidateResponseTime_thenSuccess () {når (). Get ("/ brukere / eugenp"). Deretter (). Tid (lessThan (5000L)); }

Hvis vi ønsker å validere responstiden i en annen tidsenhet, bruker vi tid() matcher med et sekund TimeUnit parameter:

@Test offentlig ugyldig nårValidateResponseTimeInSeconds_thenSuccess () {når (). Get ("/ brukere / eugenp"). Deretter (). Tid (lessThan (5L), TimeUnit.SECONDS); }

9. XML-responsbekreftelse

Ikke bare kan det validere et JSON-svar, det kan også validere XML.

La oss anta at vi ber om det // localhost: 8080 / ansatte og vi får følgende svar:

  Jane Daisy f 

Vi kan bekrefte at fornavn er Jane som så:

@Test offentlig ugyldig gittUrl_whenXmlResponseValueTestsEqual_thenCorrect () {post ("/ ansatte"). Deretter (). AssertThat () .body ("ansatte.ansatt.forstnavn", equalTo ("Jane")); }

Vi kan også bekrefte at alle verdier samsvarer med våre forventede verdier ved å koble kroppsmatchere sammen slik:

@Test offentlig ugyldig gittUrl_whenMultipleXmlValuesTestEqual_thenCorrect () {post ("/ ansatte"). Deretter (). AssertThat () .body ("ansatte.ansatt.forstnavn", equalTo ("Jane")). Kropp ("ansatte. Arbeidstaker . etternavn ", equalTo (" Daisy ")) .body (" ansatte.ansatt.sex ", equalTo (" f ")); }

Eller ved å bruke kortversjonen med variable argumenter:

@Test offentlig ugyldig gittUrl_whenMultipleXmlValuesTestEqualInShortHand_thenCorrect () {post ("/ ansatte") .then (). AssertThat (). Body ("ansatte.ansatt.forst-navn", equalTo ("Jane"), "ansatte.ansatt. Siste-) navn ", equalTo (" Daisy ")," ansatte.medarbeider.sex ", equalTo (" f ")); }

10. XPath for XML

Vi kan også bekrefte svarene våre ved hjelp av XPath. Tenk på eksemplet nedenfor som kjører en matcher på fornavn:

@Test offentlig ugyldighet gittUrl_whenValidatesXmlUsingXpath_thenCorrect () {post ("/ ansatte"). Deretter (). AssertThat (). kropp (hasXPath ("/ ansatte / ansatt / fornavn", inneholderString ("Ja")); }

XPath godtar også en alternativ måte å kjøre lik matcher:

@Test offentlig ugyldighet gittUrl_whenValidatesXmlUsingXpath2_thenCorrect () {post ("/ ansatte"). Deretter (). AssertThat () .body (hasXPath ("/ ansatte / ansatt / fornavn [text () = 'Jane']")); }

11. Loggtestdetaljer

11.1. Logg forespørselsdetaljer

La oss først se hvordan logg hele forespørselsdetaljer ved hjelp av logg (). alle ():

@Test offentlig ugyldig nårLogRequest_thenOK () {gitt (). Logg (). All () .when (). Get ("/ users / eugenp") .then (). StatusCode (200); }

Dette vil logge noe sånt som dette:

Forespørselsmetode: GET Request URI: //api.github.com:443/users/eugenp Proxy: Request params: Query params: Form params: Path params: Multiparts: Headers: Accept = * / * Cookies: Body: 

For å logge bare bestemte deler av forespørselen, har vi Logg() metode i kombinasjon med params (), body (), headers (), cookies (), method (), path () f.eks logg. (). params ().

Vær oppmerksom på at andre biblioteker eller filtre som brukes, kan endre hva som faktisk sendes til serveren, så dette bør bare brukes til å logge den opprinnelige spesifikasjonen for forespørsel.

11.2. Logg svardetaljer

På samme måte kan vi logge svardetaljene.

I det følgende eksemplet logger vi bare responsorganet:

@Test public void whenLogResponse_thenOK () {when (). Get ("/ repos / eugenp / tutorials") .then (). Log (). Body (). StatusCode (200); }

Eksempel på utdata:

{"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. Logg svar hvis tilstand oppstod

Vi har også muligheten til å logge svaret bare hvis det oppstod en feil eller statuskoden samsvarer med en gitt verdi:

@Test offentlig ugyldig nårLogResponseIfErrorOccurred_thenSuccess () {when (). Get ("/ users / eugenp") .then (). Log (). IfError (); når (). get ("/ users / eugenp") .then (). log (). ifStatusCodeIsEqualTo (500); når (). get ("/ users / eugenp") .then (). log (). ifStatusCodeMatches (greaterThan (200)); }

11.4. Logg hvis validering mislyktes

Vi kan også logge både forespørsel og svar hvis validering mislyktes:

@Test public void whenLogOnlyIfValidationFailed_thenSuccess () {when (). Get ("/ users / eugenp") .then (). Log (). IfValidationFails (). StatusCode (200); gitt (). logg (). ifValidationFails () .when (). get ("/ users / eugenp") .then (). statusCode (200); }

I dette eksemplet vil vi validere at statuskoden er 200. Bare hvis dette mislykkes, logges forespørselen og svaret.

12. Konklusjon

I denne opplæringen har vi det utforsket det REST-sikre rammeverket og så på de viktigste funksjonene vi kan bruke til å teste våre RESTful-tjenester og validere svarene deres.

Full implementering av alle disse eksemplene og kodebiter finner du i det REST-sikre GitHub-prosjektet.

Jackson bunn

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET