REST API testiranje s krastavcem

1. Pregled

Ovaj tutorial daje uvod u Krastavac, uobičajeni alat za testiranje prihvaćanja korisnika i kako ga koristiti u testovima REST API.

Uz to, da bismo članak učinili samostalnim i neovisnim o bilo kojim vanjskim REST uslugama, upotrijebit ćemo WireMock, biblioteku web usluga koja potiče i ismijava. Ako želite znati više o ovoj knjižnici, pogledajte uvod u WireMock.

2. Kornišon - jezik krastavca

Krastavac je okvir za testiranje koji podržava razvoj usmjeren na ponašanje (BDD), omogućavajući korisnicima da definiraju radnje aplikacija u običnom tekstu. Djeluje na temelju jezika specifičnog za Gherkin domenu (DSL). Ova jednostavna, ali moćna sintaksa Gherkin omogućuje programerima i testerima da napišu složene testove, a da ih razumiju čak i netehničkim korisnicima.

2.1. Uvod u Gherkin

Gherkin je linijski orijentirani jezik koji koristi završetke redaka, udubljenja i ključne riječi za definiranje dokumenata. Svaki neprazan redak obično započinje ključnom riječi Gherkin, nakon čega slijedi proizvoljan tekst, koji je obično opis ključne riječi.

Cijela struktura mora biti zapisana u datoteku s značajka produžetak koji će prepoznati krastavac.

Evo jednostavnog primjera Gherkin dokumenta:

Značajka: Kratki opis željene funkcionalnosti Scenarij: poslovna situacija s obzirom na preduvjet i još jedan preduvjet kada se dogodi događaj i dogodi se i drugi događaj tada se postiže provjerljivi ishod i nešto drugo je također dovršeno

U sljedećim odjeljcima opisat ćemo nekoliko najvažnijih elemenata u Gherkin strukturi.

2.2. Značajka

Datoteku Gherkin koristimo za opis značajke aplikacije koju treba testirati. Datoteka sadrži Značajka ključna riječ na samom početku, nakon čega slijedi naziv značajke u istom retku i neobavezni opis koji može obuhvaćati više redaka ispod.

Parser za krastavce preskače sav tekst, osim za Značajka i uključuje je samo u svrhu dokumentacije.

2.3. Scenariji i koraci

Struktura kornišona može se sastojati od jednog ili više scenarija koje prepoznaje Scenarij ključna riječ. Scenarij je u osnovi test koji omogućava korisnicima da provjere sposobnost aplikacije. Treba opisati početni kontekst, događaje koji se mogu dogoditi i očekivane ishode stvorene tim događajima.

Te se stvari rade pomoću koraka identificiranih jednom od pet ključnih riječi: S obzirom, Kada, Zatim, I, i Ali.

  • S obzirom: Ovaj korak je dovođenje sustava u točno definirano stanje prije nego što korisnici počnu komunicirati s aplikacijom. A S obzirom klauzula može se smatrati preduvjetom za slučaj upotrebe.
  • Kada: A Kada korak se koristi za opis događaja koji se događa aplikaciji. To može biti radnja koju su poduzeli korisnici ili događaj koji je pokrenuo drugi sustav.
  • Zatim: Ovaj korak određuje očekivani ishod testa. Ishod bi trebao biti povezan s poslovnim vrijednostima značajke koja se ispituje.
  • I i Ali: Ove se ključne riječi mogu koristiti za zamjenu gornjih ključnih riječi kada postoji više koraka iste vrste.

Krastavac zapravo ne razlikuje ove ključne riječi, ali ipak su tu kako bi značajku učinili čitljivijom i dosljednijom strukturi BDD.

3. Provedba krastavca-JVM

Krastavac je izvorno napisan na Ruby-u, a prebačen je na Javu implementacijom Cucumber-JVM, što je i predmet ovog odjeljka.

3.1. Ovisnosti Mavena

Da bi se Cucumber-JVM koristio u projektu Maven, u POM treba uključiti sljedeću ovisnost:

 io. krastavac krastavac-java 6.8.0 test 

Da bismo olakšali JUnit testiranje s krastavcem, moramo imati još jednu ovisnost:

 io. krastavac krastavac-junit 6.8.0 

Alternativno, možemo koristiti drugi artefakt kako bismo iskoristili lambda izraze u Javi 8, koji neće biti obrađeni u ovom vodiču.

3.2. Definicije koraka

Scenariji kornišona bili bi beskorisni da se ne pretoče u akcije i tu u obzir dolaze definicije koraka. U osnovi, definicija koraka je anotirana Java metoda s priloženim uzorkom čiji je zadatak pretvoriti Gherkin korake u običnom tekstu u izvršni kôd. Nakon raščlanjivanja značajke dokumenta, Krastavac će tražiti definicije koraka koje se podudaraju s unaprijed definiranim Gherkinovim koracima za izvršenje.

Da bismo to učinili jasnijim, pogledajmo sljedeći korak:

S obzirom da sam prijavio tečaj u Baeldungu

I definicija koraka:

@Given ("Registrirao sam tečaj u Baeldungu") javna praznina verifyAccount () {// implementacija metode}

Kad Krastavac pročita zadani korak, tražit će definicije koraka čiji se obrasci označavanja podudaraju s Gherkinovim tekstom.

4. Izrada i izvođenje testova

4.1. Pisanje datoteke značajke

Počnimo s deklariranjem scenarija i koraka u datoteci s nazivom koji završava na .obilježje produžetak:

Značajka: Testiranje REST API-ja Korisnici bi trebali biti u mogućnosti podnijeti GET i POST zahtjeve web usluzi, koju predstavlja WireMock Scenarij: Prijenos podataka na web uslugu Kada korisnici prenose podatke na projekt Tada bi poslužitelj to trebao riješiti i vratiti status uspjeha Scenarij: Dohvaćanje podataka s web usluge Kada korisnici žele dobiti informacije o projektu 'Krastavac' Tada se vraćaju traženi podaci

Sada ovu datoteku spremamo u direktorij s imenom Značajka, pod uvjetom da će se direktorij učitati u stazu za vrijeme izvođenja, npr. src / glavni / resursi.

4.2. Konfiguriranje JUnit-a za rad s krastavcem

Da bi JUnit bio svjestan Krastavca i čitao datoteke značajki tijekom pokretanja, Krastavac klasa mora biti deklarirana kao Trkač. Također moramo reći JUnit mjestu da traži datoteke značajki i definicije koraka.

@RunWith (Cucumber.class) @CucumberOptions (features = "classpath: Feature") javna klasa CucumberIntegrationTest {}

Kao što vidite, značajke element od Opcija krastavaca pronalazi datoteku značajki stvorenu prije. Još jedan važan element, tzv ljepilo, pruža putove do definicija koraka. Međutim, ako su definicije testnog slučaja i koraka u istom paketu kao u ovom vodiču, taj će element možda pasti.

4.3. Pisanje definicija koraka

Kada Krastavac raščlani korake, tražit će metode označene ključnim riječima Gherkin kako bi pronašao odgovarajuće definicije koraka.

Izraz definicije koraka može biti redoviti izraz ili izraz krastavaca. U ovom uputstvu koristit ćemo izraze krastavaca.

Slijedi metoda koja u potpunosti odgovara koraku Gherkin-a. Metoda će se koristiti za objavljivanje podataka na REST web usluzi:

@ Kada ("korisnici prenose podatke o projektu") javni void usersUploadDataOnAProject () baca IOException {}

A ovdje je metoda koja odgovara koraku Gherkin-a i uzima argument iz teksta, koji će se koristiti za dobivanje informacija s REST web usluge:

@ Kada ("korisnici žele dobiti informacije o projektu {string}") javni void usersGetInformationOnAProject (Niz projektaName) baca IOException {}

Kao što vidite, usersGetInformationOnAProject metoda traje a Niz argument, što je naziv projekta. Ovaj argument deklarira {niz} u bilješci i ovdje odgovara Krastavac u tekstu koraka.

Alternativno bismo mogli upotrijebiti regularni izraz:

@ Kada ("^ korisnici žele dobiti informacije o '(. +)' Projektu $") javni void usersGetInformationOnAProject (String projectName) baca IOException {}

Napomena, ‘^' i ‘$' koji prema tome označavaju početak i kraj regularnog izraza. Dok ‘(.+)' odgovara Niz parametar.

U sljedećem ćemo odjeljku pružiti radni kod za obje gore navedene metode.

4.4. Izrada i izvođenje testova

Prvo ćemo započeti s JSON strukturom kako bismo ilustrirali podatke prenesene na poslužitelj POST zahtjevom i preuzete na klijenta pomoću GET-a. Ova je struktura spremljena u jsonString polje, a prikazano dolje:

{"test-framework": "krastavac", "podržani jezik": ["Ruby", "Java", "Javascript", "PHP", "Python", "C ++"], "web stranica": "krastavac. io "}

Da bismo demonstrirali REST API, koristimo WireMock poslužitelj:

WireMockServer wireMockServer = novi WireMockServer (options (). DynamicPort ());

Uz to, koristit ćemo Apache HttpClient API za predstavljanje klijenta koji se koristi za povezivanje s poslužiteljem:

CloseableHttpClient httpClient = HttpClients.createDefault ();

Sada, prijeđimo na pisanje koda za testiranje unutar definicija koraka. To ćemo učiniti za usersUploadDataOnAProject metoda prva.

Poslužitelj bi trebao biti pokrenut prije nego što se klijent poveže s njim:

wireMockServer.start ();

Korištenje WireMock API-ja za zaustavljanje REST usluge:

configureFor ("localhost", wireMockServer.port ()); stubFor (post (urlEqualTo ("/ create")) .withHeader ("content-type", jednakTo ("application / json")) .withRequestBody (sadrži ("testing-framework")) .willReturn (aResponse (). withStatus (200)));

Sada pošaljite POST zahtjev sa sadržajem preuzetim iz jsonString polje deklarirano gore poslužitelju:

Zahtjev za HttpPost = novi HttpPost ("// localhost:" + wireMockServer.port () + "/ create"); StringEntity entitet = novi StringEntity (jsonString); request.addHeader ("vrsta sadržaja", "aplikacija / json"); request.setEntity (entitet); HttpResponse odgovor = httpClient.execute (zahtjev);

Sljedeći kod tvrdi da je POST zahtjev uspješno primljen i obrađen:

assertEquals (200, response.getStatusLine (). getStatusCode ()); provjeri (postRequestFor (urlEqualTo ("/ create")) .withHeader ("content-type", jednakTo ("application / json")));

Poslužitelj bi se trebao zaustaviti nakon upotrebe:

wireMockServer.stop ();

Druga metoda koju ćemo ovdje primijeniti je usersGetInformationOnAProject (Niz projektaName). Slično prvom ispitivanju, moramo pokrenuti poslužitelj, a zatim ugasiti REST uslugu:

wireMockServer.start (); configureFor ("localhost", wireMockServer.port ()); stubFor (get (urlEqualTo ("/ projects / cucumber")) .withHeader ("accept", jednakTo ("application / json")) .willReturn (aResponse (). withBody (jsonString)));

Podnošenje GET zahtjeva i primanje odgovora:

HttpGet zahtjev = novi HttpGet ("// localhost:" + wireMockServer.port () + "/ projects /" + projectName.toLowerCase ()); request.addHeader ("prihvati", "application / json"); HttpResponse httpResponse = httpClient.execute (zahtjev);

Pretvorit ćemo httpResponse promjenjiva na a Niz pomoću pomoćne metode:

Niz responseString = convertResponseToString (httpResponse);

Evo implementacije te pomoćne metode pretvorbe:

private String convertResponseToString (HttpResponse response) baca IOException {InputStream responseStream = response.getEntity (). getContent (); Skener skenera = novi Skener (responseStream, "UTF-8"); String responseString = scanner.useDelimiter ("\ Z"). Next (); scanner.close (); povratak responseString; }

Sljedeće potvrđuje cijeli postupak:

assertThat (responseString, containsString ("\" test-framework \ ": \" krastavac \ "")); assertThat (responseString, containsString ("\" web stranica \ ": \" cucumber.io \ "")); provjeri (getRequestFor (urlEqualTo ("/ projects / cucumber")) .withHeader ("accept", jednakTo ("application / json")));

Napokon, zaustavite poslužitelj kako je gore opisano.

5. Pokretanje značajki u paraleli

Cucumber-JVM izvorno podržava paralelno izvršavanje testa na više niti. Koristit ćemo JUnit zajedno s Maven Failsafe dodatkom za izvršavanje trkača. Alternativno bismo mogli koristiti Maven Surefire.

JUnit pokreće datoteke značajki paralelno, a ne scenarije, što znači svi scenariji u datoteci značajki izvršavat će se istom niti.

Dodajmo sada konfiguraciju dodatka:

 maven-failsafe-plugin $ {maven-failsafe-plugin.version} CucumberIntegrationTest.java metode 2 integracija-test provjera 

Imajte na umu da:

  • paralelno: Može biti satovi, metode, ili oboje - u našem slučaju, razreda učinit će da se svaka ispitna klasa izvodi u zasebnoj niti
  • threadCount: označava koliko niti treba biti dodijeljeno za ovo izvršavanje

To je sve što moramo učiniti da paralelno pokrenemo značajke Krastavca.

6. Zaključak

U ovom smo tutorijalu pokrili osnove krastavca i kako ovaj okvir koristi jezik specifičan za domenu Gherkin za testiranje REST API-ja.

Kao i obično, svi uzorci koda prikazani u ovom vodiču dostupni su na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found