Testirajte REST API s Javom

1. Pregled

Ovaj se vodič usredotočuje na osnovna načela i mehaniku testiranje REST API-a s integracijskim testovima uživo (s JSON korisnim opterećenjem).

Glavni je cilj pružiti uvod u testiranje osnovne ispravnosti API-ja - a mi ćemo za primjere koristiti najnoviju verziju GitHub REST API-ja.

Za internu aplikaciju, ova vrsta testiranja obično će se izvoditi kao kasni korak u procesu kontinuirane integracije, trošeći REST API nakon što je već postavljen.

Pri testiranju REST resursa, obično postoji nekoliko pravokutnih odgovornosti na koje bi se testovi trebali usredotočiti:

  • HTTP kod odgovora
  • drugi HTTP zaglavlja u odgovoru
  • the korisni teret (JSON, XML)

Svaki bi se test trebao usredotočiti samo na jednu odgovornost i sadržavati jednu tvrdnju. Fokusiranje na jasno razdvajanje uvijek ima koristi, ali kada je provođenje ove vrste testiranja crne kutije još je važnije, jer je općenita tendencija pisanja složenih testnih scenarija na samom početku.

Sljedeći važan aspekt integracijskih testova je poštivanje Načelo jedne razine apstrakcije - logika unutar testa trebala bi biti napisana na visokoj razini. Pojedinosti poput izrade zahtjeva, slanja HTTP zahtjeva poslužitelju, bavljenja IO-om itd. Ne smiju se obavljati u redu već pomoću uslužnih metoda.

2. Testiranje statusnog koda

@Test public void givenUserDoesNotExists_whenUserInfoIsRetrieved_then404IsReceived () baca ClientProtocolException, IOException {// Dano ime niza = RandomStringUtils.randomAlphabetic (8); Zahtjev za HttpUriRequest = novi HttpGet ("//api.github.com/users/" + ime); // Kada je HttpResponse httpResponse = HttpClientBuilder.create (). Build (). Izvršiti (zahtjev); // Zatim assertThat (httpResponse.getStatusLine (). GetStatusCode (), jednakTo (HttpStatus.SC_NOT_FOUND)); }

Ovo je prilično jednostavan test - provjerava radi li osnovni sretni put, bez dodavanja previše složenosti ispitnom paketu.

Ako iz bilo kojeg razloga ne uspije, nema potrebe tražiti bilo koji drugi test za ovaj URL dok se to ne popravi.

3. Testiranje vrste medija

@Test public void givenRequestWithNoAcceptHeader_whenRequestIsExecuted_thenDefaultResponseContentTypeIsJson () baca ClientProtocolException, IOException {// Dat je niz jsonMimeType = "application / json"; Zahtjev za HttpUriRequest = novi HttpGet ("//api.github.com/users/eugenp"); // Kada je odgovor HttpResponse = HttpClientBuilder.create (). Build (). Izvršenje (zahtjev); // Zatim String mimeType = ContentType.getOrDefault (response.getEntity ()). GetMimeType (); assertEquals (jsonMimeType, mimeType); }

To osigurava da Odgovor zapravo sadrži JSON podatke.

Kao što ste mogli primijetiti, pratimo logično napredovanje testova - prvo kod statusa odgovora (kako bi se osiguralo da je zahtjev u redu), zatim vrsta medija odgovora i tek ćemo u sljedećem testu pogledati stvarnu nosivost JSON-a.

4. Testiranje JSON korisnog tereta

@Test javna praznina givenUserExists_whenUserInformationIsRetrieved_thenRetrievedResourceIsCorrect () baca ClientProtocolException, IOException {// Dat je HttpUriRequest zahtjev = novi HttpGet ("//api.github.com/users/eugenp; // Kada je odgovor HttpResponse = HttpClientBuilder.create (). Build (). Izvršenje (zahtjev); // Tada je resurs GitHubUser = RetrieveUtil.retrieveResourceFromResponse (odgovor, GitHubUser.class); assertThat ("eugenp", Matchers.is (resource.getLogin ())); }

U ovom slučaju znam da je zadani prikaz GitHub resursa JSON, ali obično je Vrsta sadržaja zaglavlje odgovora treba testirati uz Prihvatiti zaglavlje zahtjeva - klijent traži određenu vrstu predstavljanja putem Prihvatiti, koju bi poslužitelj trebao ispoštovati.

5. Uslužni programi za ispitivanje

Upotrijebit ćemo Jackson 2 za demarširanje sirovog JSON Stringa u tipski Java entitet:

javna klasa GitHubUser {prijava s privatnim nizom; // standardni geteri i postavljači}

Koristimo samo jednostavni uslužni program da testovi budu čisti, čitljivi i na visokoj razini apstrakcije:

javna statička T retrieveResourceFromResponse (odgovor HttpResponse, klasa klazz) baca IOException {String jsonFromResponse = EntityUtils.toString (response.getEntity ()); ObjectMapper mapper = novi ObjectMapper () .configure (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); vratiti mapper.readValue (jsonFromResponse, clazz); }

Primijetite da Jackson zanemaruje nepoznata svojstva koja nam GitHub API šalje - to je jednostavno zato što predstavljanje korisničkog resursa na GitHubu postaje prilično složeno - i ovdje nam ne trebaju nikakve informacije.

6. Ovisnosti

Uslužni programi i testovi koriste sljedeće knjižnice, sve dostupne u Maven central:

  • HttpClient
  • Jackson 2
  • Hamcrest (neobavezno)

7. Zaključak

Ovo je samo jedan dio onoga što bi trebao biti cjeloviti paket za testiranje integracije. Testovi su usredotočeni na osiguravajući osnovnu ispravnost za REST API, bez ulaska u složenije scenarije,

Na primjer, nisu obuhvaćeni sljedeći podaci: Otkrivenost API-ja, potrošnja različitih prikaza za isti resurs itd.

Provedbu svih ovih primjera i isječaka koda možete pronaći na Githubu - ovo je projekt zasnovan na Mavenu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.