Poştaş este un instrument excelent pentru explorarea API-urilor REST. Puteți crea cereri și le puteți încerca pentru a obține feedback rapid. Apoi le puteți persista ca colecții pentru a vă asigura că cunoștințele nu se pierd.

Om nou, versiunea CLI a Postman, vă permite să treceți la nivelul următor și să transformați o colecție într-o suită de teste automate end-to-end. Această suită va rula apoi în instrumentul dvs. CI ales. În acest articol voi explora avantajele acestui lucru și vă voi arăta cum să îl configurați.

intro

Ce este un test End-to-End în contextul unui API?

Testarea nomenclaturii este un lucru dificil. Păstrarea testarea piramidei în minte, le putem imagina ca teste de nivel foarte înalt. Aceste teste confirmă faptul că un anumit API REST funcționează conform intenției, tratând internele ca o cutie neagră. Nu implicăm nicio interfață de utilizare în proces, ceea ce ajută la reducerea fulgerului.

poke-e2e
de geek & poke / CC BY

Testele fulgiante sunt extrem de enervante, așa cum a experimentat la un moment dat fiecare dezvoltator. În loc să ne lovim cu capul de perete încercând să reparăm nefixabilul, putem atenua problema utilizând teste de nivel inferior.

De ce ar trebui să fac aceste teste?

Aș dori să abordez două scenarii diferite:

Primul este testarea propriilor API-uri REST. Aceste teste adaugă un strat suplimentar de încredere. Cu siguranță, utilizați un amestec sănătos de teste diferite (unitate, integrare, funcțional, …). Testele de la cap la cap pot fi confirmarea finală a faptului că totul arată bine.

Al doilea caz este testarea API-urilor pe care nu le controlați. În ultimele mele proiecte, majoritatea datelor pe care le-am consumat provin din API-uri servite de alte echipe. De mai multe ori am petrecut o jumătate de zi depanând o eroare în aplicația mea, doar pentru a observa că un API din aval a fost borked tot timpul. Testele automate acoperă această integrare și ajută la izolarea problemelor.

Documentare vie

O colecție de teste care se execută în mod regulat servește drept cea mai bună documentație pentru un API. Ați căutat ceva în vreun wiki corporativ în ultima vreme? Dacă găsești ceva, ar trebui să fii fericit. Va fi probabil incomplet. Sau pur și simplu greșit. Vremuri amuzante.

Monitorizarea

În ambele cazuri, aceste teste se pot transforma de la o poartă de acces în procesul de construcție la un instrument de monitorizare activ. Executându-le în mod constant, vă asigurați că API-ul se comportă în continuare așa cum vă așteptați. În caz contrar, alarmele potrivite vor fi declanșate. Nu vrei să realizezi că ceva nu este în regulă doar atunci când un client se plânge.

De ce nu folosiți în schimb teste contractuale bazate pe consumatori?

Întrebare grozavă, dacă pot să spun și eu. CDC-uri sunt o modalitate excelentă de a vă asigura că un API este conform cu ceea ce un client așteaptă de la acesta. Dacă le puteți configura corect, acestea vor înlocui testele de la capăt la cap aproape complet. Amintiți-vă, continuați să împingeți testele la un nivel inferior oricând puteți.

Totuși, nu funcționează în orice situație. Dacă nu controlați atât furnizorul, cât și consumatorul, trebuie să vă bazați pe o altă parte. Dacă nu își îndeplinesc partea din contract, testele vor fi inutile. Unele echipe nu sunt doar în poziția de a efectua în mod continuu teste împotriva unui contract. Rularea propriilor teste ar putea fi cel mai bun pariu.

Oricum, după ce am expus rațiunea, este timpul pentru unii cod.

Crearea unei colecții Postman

Colecția

Definim un număr de apeluri care vor fi executate secvențial în interiorul CI-ului nostru. Fiecare apel execută o cerere împotriva API-ului. Apoi rulează câteva teste pentru a verifica dacă solicitarea a avut succes, verificând codul de stare și corpul.

Pentru a crea colecția, tind să folosesc aplicația Postman. Îmi place să extrag lucruri precum adrese URL și parametri într-un mediu inconjurator. Apoi, configurarea acestuia devine mai ușoară și nu aveți nicio informație sensibilă în colecția în sine. Istoria ta este o un loc convenabil pentru a începe construirea acestei colecții.

Odată ce sunteți mulțumit de colecție, îl puteți exporta ca fișier JSON. Acest fișier poate fi angajat în controlul sursă pentru a servi ca bază pentru conducta care va rula testele. Există o versiune Pro și Enterprise care ajută la gestionarea colecțiilor, pe care nu am încercat-o cu adevărat. Totuși, un bun git depozitul este mai mult decât suficient pentru a începe să ruleze.

export-poștaș

Rularea colecției

Până acum am folosit Postman obișnuit și nimic altceva. Acum este momentul ca noul om să strălucească. Despre ce vorbesc, oricum? Voi cita documente oficiale direct:

Newman este o linie de comandă de colectare Runner pentru Postman. Vă permite să rulați și să testați o colecție Postman direct din linia de comandă.

Bine că am clarificat asta! Este instalat ca pachet npm, ceea ce poate duce la un package.json la fel de simplu ca acesta:

{
  "name": "postman-utils",
  "version": "0.0.1",
  "private": true,
  "description": "Postman utilities",
  "scripts": {
    "newman": "node_modules/.bin/newman run"
  },
  "dependencies": {
    "newman": "^4.4.1"
  }
}

așa cum am menționat anterior, nu doriți să codificați variabile precum URL-uri, parametri sau, Doamne ferește, parole în acea colecție. Nu este flexibil și nu este sigur. În schimb, îmi place să folosesc un fișier de configurare care include toate aceste valori. Dar dacă vrem să comitem acel fișier, trebuie totuși să găsim o modalitate de a evita introducerea secretelor acolo. Îl folosesc ca șablon și înlocuiesc valorile la rulare cu envsubst. Fișierul de configurare arată astfel

{
	"id": "425cf4df-d994-4d91-9efb-41eba1ead456",
	"name": "echo",
	"values": [
		{
			"key": "host",
			"value": "${HOST}",
			"enabled": true
		}
	]
}

Puteți orchestra acest lucru cu un script bash simplu. Scriptul injectează variabilele în șablon, rulează newman și șterge fișierele pentru a evita scurgerile. Merge foarte bine cu gopass, unde vă puteți stoca în siguranță secretele și le puteți prelua prin script.

setup-newman() {
  settings=/tmp/settings.json.$$
  result=/tmp/variables.json.$$

  # shellcheck disable=SC2064
  trap "rm -f "$settings" "$result"" EXIT
}

run-newman() {
  local service=${1?You need to provide the service to check}

  envsubst < "$service.environment.json.template" > "$settings"

  npx newman run "$service.json" 
      -e "${settings}" 
      --export-environment "${result}"
}

acel ajutor poate fi apelat cu colecția pe care doriți să o testați. Variabilele exportate vor fi selectate de envsubst. npx ne oferă un pic mai multă flexibilitate în găsirea newman binar, în cazul în care nu doriți să utilizați un package.json dar instalați-l la nivel global.

goal_check-service() {
  setup

  export SERVICE_PASSWORD=${SERVICE_PASSWORD:-$(gopass store/service/password)}

  run_newman service
}

Teste

Efectuarea unei cereri nu este decât primul pas. Amintiți-vă, ne propunem să construim o suită de testare. Avem o filă de testare convenabilă în Postman pe care o putem folosi pentru a scrie testele noastre.

tab-test

Testele noastre sunt scrise în JavaScript, folosind Chai. Să presupunem că vreau să testez că apelul meu a furnizat o listă de rezultate, aș putea să o fac așa:

var getResults = function() {
    var jsonData = pm.response.json();
    return jsonData['results'];
};

pm.test("Request was successful", function () {
    pm.response.to.have.status(200);
});

pm.test("There are results", function () {
    pm.expect(getResults().length).to.be.above(0);
});

Mai multe detalii pot fi găsite Aici

Fluxuri de clădire

Toate apelurile dintr-o colecție sunt executate secvențial. Acest lucru ne oferă posibilitatea de a testa fluxuri întregi în loc de apeluri simple. Un astfel de flux pentru un /posts resursa este:

  • Obțineți o listă cu toate posts
  • Adu-l pe primul post În listă
  • Actualizați fișierul post

Vom construi o suită de teste parametrizate care vor continua să funcționeze în timp, nu doar prima dată când l-ați rulat. O parte importantă a acestui lucru este modificarea mediului într-o cerere. Acesta este modul nostru de a transmite parametrii între cereri. Să presupunem că prima noastră solicitare a avut succes, după cum confirmă testele noastre. Apoi stocăm ID-ul pe o variabilă care va fi utilizată pentru a prelua o anumită entitate.

// First result in the list
var post = getResults()[0];

// Pass variables to other stages
pm.environment.set("id", post.id)

Următoarea solicitare poate utiliza acel parametru ca oricare pe care îl setăm manual.

Ignorarea apelurilor pe baza unei condiții

Fluxurile ar putea avea nevoie de o anumită logică pentru a omite anumite cereri. Să presupunem că aveți o solicitare care creează o nouă entitate prin intermediul unui POST. Doriți să aveți această solicitare, dar este posibil să nu doriți să o rulați la fiecare comitere. Poate vrei doar să o faci o dată pe zi. În acest caz, vom ignora testul pe baza unei anumite variabile.

// Do not run create request in sequence, unless executeCreate is set to true
if(!pm.environment.get("executeCreate")) {
    postman.setNextRequest('Get other posts')
}

Variabila intră în fișierul de configurare și este setată la o variabilă de mediu care se injectează prin scriptul nostru, așa cum am arătat mai sus.

Este timpul pentru o integrare continuă

În acest moment ar trebui să aveți o colecție care rulează local. Rularea asta o dată este în regulă, dar de ce nu o rulați pentru fiecare comitere? Sau poate la fiecare oră, dacă doriți să verificați un API pe care nu îl controlați?

Conducta dvs. CI este un loc perfect pentru a face acest lucru. O să folosesc Cerc CI pentru exemplul meu, dar orice CI va face. Execut testele în interiorul unui imagine docker pe care l-am construit, care include toate dependențele necesare. Există deja o imagine oficială Docker oferită de Postman. Cu toate acestea, nu conține envsubst și folosește un vechi NodeJS versiune.

Scriptul de ajutor pe care l-am construit în pasul anterior va funcționa fără modificări în CircleCI. Trebuie doar să oferim secretele necesare ca variabile. Aceasta este treaba:

  healthcheck:

    docker:
      - image: sirech/newman-executor:12.6

    steps:
      - checkout
      - run: ./go test-e2e

care va produce un raport similar cu acesta:

ieșire

Dar alternativele?

Multe cadre oferă propriul lor mod de a rula teste împotriva unui API care rulează. În Cizma de primăvară, de exemplu, puteți utiliza MockMvc pentru a testa controlere. Puteți folosi ambele, în opinia mea. Mai întâi testele native, ca să spunem așa, și apoi acoperiți testele Postman deasupra.

Și să nu uităm de ol răsuci. Am avut o colecție uriașă de comenzi curl cu care am testat un API necesar pentru ultimul meu proiect. Cu toate acestea, gestionarea acestui lucru devine din ce în ce mai obositoare în timp. Dacă doriți să utilizați trimiterea de cereri complexe, cum ar fi certificate sau cookie-uri, Postman este mult mai convenabil de utilizat. Mai mult, puteți folosi JavaScript în loc de bash, ceea ce poate face lucrurile puțin mai ușor de citit și întreținut.

Ce altceva?

Acest lucru este deja destul de mult și este doar începutul. Tot ceea ce faceți cu un API îl puteți automatiza. De exemplu, în proiectul meu anterior am avut o colecție care rulează un OAuth Flow. Aceasta ne-a adus un indicativ pe care l-am putea folosi pentru a face cereri împotriva unui punct final autorizat.

O repo de utilizat ca exemplu

Aici este un depozit pentru o aplicație Kotlin care rulează o colecție Postman ca test e2e. Poate servi ca un kit de pornire pentru a începe cu teste API End-to-End de înaltă calitate.