Kuidas testida Gopeci rakendust musta värviga RSpec-iga

Automaatne testimine on tänapäeval veebiarenduses raevunud kogu maailmas. Hästi kirjutatud test vähendab dramaatiliselt rakenduse tahtmatu purunemise riski, kui lisate uusi funktsioone või parandate vead. Kui teil on keeruline süsteem, mis on ehitatud mitmest üksteisega interaktsioonis olevast komponendist, on uskumatult raske testida, kuidas iga komponent toimib koos teiste komponentidega.

Vaatame, kuidas kirjutada häid automaatseid katseid komponentide arendamiseks Go's ja kuidas seda teha RSpeci teegi abil Ruby on Railsis.

Lisamine Mine meie projekti tehnoloogiapaketti

Üks projekt, mille kallal ma oma ettevõttes töötan, eTeam, võib jagada administraatoripaneeliks, kasutaja armatuurlauaks, aruannete generaatoriks ja päringute töötlejaks, mis haldab rakendusse integreeritud erinevate teenuste taotlusi.

Projekti osa, mis töötleb taotlusi, on kõige olulisem, seetõttu pidime maksimeerima selle töökindlust ja kättesaadavust.

Monoliitse rakenduse osana on suur viga, et taotlusprotsessorit mõjutavad vead, isegi kui rakenduse osades, mis pole sellega seotud, muutuvad koodid. Samuti on oht päringuprotsessori krahhiks, kui muud komponendid on suure koorma all. Rakenduse Ngnixi töötajate arv on piiratud, mis võib koormuse suurenemisel probleeme põhjustada. Näiteks kui halduspaneelil avatakse korraga mitu ressursimahukat lehte, aeglustab protsessor kogu rakendust või isegi jookseb selle alla.

Need riskid ja ka kõnealuse süsteemi küpsus - me ei pidanud kuude kaupa suuri muudatusi tegema - tegid selle rakenduse ideaalseks kandidaadiks eraldi teenuse loomiseks päringute töötlemiseks.

Otsustasime kirjutada eraldi teenuse Go, mis jagas juurdepääsu andmebaasile rakendusega Rails, mis vastutas tabeli struktuuri muutuste eest. Ainult kahe rakenduse korral töötab selline jagatud andmebaasiga skeem suurepäraselt. See nägi välja järgmine:

Kirjutasime ja juurutasime teenuse eraldi Rails-eksemplaris. Nii ei olnud vaja muretseda, kui rakenduse Rails kasutuselevõtmine mõjutab päringu töötlejat. Teenus võtab otse HTTP-päringuid vastu ilma Ngnixita ja ei kasuta palju mälu. Võite seda nimetada minimalistlikuks rakenduseks!

Probleem ühiku testimisega Go-is

Lõime Go rakenduse jaoks ühiskatsed, kus kõiki andmebaasitaotlusi mõnitati. Lisaks muudele selle lahenduse argumentidele vastutas andmebaasi struktuuri eest ka pearakendus Rails, seega puudus Go rakendusel tegelikult testandmebaasi loomise teave. Töötlemise pool moodustas äriloogika, teine ​​pool aga andmebaasipäringud, mida kõiki pilkati.

Pilkatud objektid on Go-is palju vähem loetavad kui Ruby puhul. Iga kord, kui andmebaasist andmete lugemiseks lisati uusi funktsioone, pidime paljude varem toiminud ebaõnnestunud testide ajal pilkitud objekte lisama. Lõpuks ei osutunud sellised ühikatsetused eriti tõhusaks ja olid äärmiselt habras.

Meie lahendus

Nende puuduste korvamiseks otsustasime teenuse Rails rakenduses katta funktsionaalsete testidega ja testida teenust Go nagu must kast. Valge kasti testimine ei toimiks igal juhul, kuna Ruby abil oli võimatu teenuse sisse pääseda ja vaadata, kas meetodit kutsutakse.

See tähendab ka, et testteenuse kaudu saadetud taotlusi ei olnud samuti võimalik pilkata, seega vajasime nende testide haldamiseks ja kirjutamiseks veel ühte rakendust. Toimiks midagi RequestBini sarnast, kuid see pidi toimima kohapeal. Oleme juba kirjutanud utiliidi, mis selle triki teeb, nii et otsustasime proovida seda kasutada.

Selle tulemuseks oli seadistus:

  1. RSpec kompileerib ja käivitab Go-binaari koos konfiguratsiooniga, milles on täpsustatud juurdepääs testiandmebaasile, koos konkreetse pordiga HTTP-taotluste vastuvõtmiseks, st 8082.
  2. Samuti töötab see utiliit, mis registreerib pordi 8083 saabuvad HTTP-taotlused.
  3. Kirjutame regulaarselt RSpecis teste. See loob andmebaasis vajalikud andmed ja saadab päringu localhost: 8082 justkui välise teenuse, näiteks HTTParty jaoks.
  4. Sõelume vastuse, kontrollime muudatusi andmebaasis, saame loendi päringutest, mille on asendanud RequestBin asendaja, ja kontrollime neid.

Rakendamise üksikasjad

Selle rakendasime järgmiselt. Demonstratsioonina helistagem testteenusele TheService ja looge ümbris:

Väärib märkimist, et automaatse laadimise failid tuleb RSpeci kasutamisel konfigureerida tugikaustas:

Rež [Rails.root.join ('spec / support / ** / *. Rb')]. Kumbki {| f | nõua f}

Algusmeetod:

  • Loeb TheService käivitamiseks vajalikku konfiguratsiooniteavet. See teave võib erinevatel arendajatel erineda ja on seetõttu Gitist välja jäetud. Konfiguratsioon sisaldab programmi käivitamiseks vajalikke sätteid. Kõik need erinevad konfiguratsioonid asuvad ühes kohas, nii et te ei pea tarbetuid faile looma.
  • Kompileerib ja jookseb läbi käima
  • Küsitleb iga sekund ja ootab, kuni TheService on valmis taotlusi vastu võtma.
  • Salvestab iga protsessi identifikaatori, et mitte midagi korrata ja võimalust protsessi peatada.

Konfiguratsioon ise:

Peatamise meetod peatab protsessi lihtsalt. Seal on küll olemas! Ruby käivitab käsu minna käima, mis kompileerib TheServicei ja käivitab tundmatu ID-ga lapseprotsessis binaari. Kui peatame lihtsalt Ruby'is toimuva protsessi, siis lapseprotsess ei peatu automaatselt ja port jääb kasutamiseks. Seega peab TheService'i peatamine läbima protsessigrupi ID:

Järgmisena valmistame ette jagatud konteksti, kus määratleme vaikemuutujad, käivitame teenuse TheService, kui see pole veel käivitatud, ja lülitame videomaki ajutiselt välja, kuna videomakk näeks, mida me teeme välise teenuse päringuna, kuid me ei soovi Videomakk taotluste pilkamiseks sellel hetkel:

Ja nüüd võime vaadata spetsifikatsioonide kirjutamist ise:

Teenus saab teha HTTP-päringuid välistele teenustele. Saame selle konfigureerida suunama taotlused kohalikku utiliiti, mis neid logib. Selle utiliidi jaoks on olemas ka ümbris selle käivitamiseks ja peatamiseks, mis sarnaneb 'TheServiceControl'iga, välja arvatud see, et selle utiliidi saab käivitada lihtsalt binaarsena ilma kompileerimiseta.

Täiendavad olulisemad punktid

Go rakendus kirjutati nii, et kõik logid ja silumisteave saadetaks STDOUT-i. Tootmise ajal saadetakse see väljund faili. RSpecist käivitamisel kuvatakse logi konsoolis, mis aitab silumisest kindlasti.

Kui juhite spetsifikatsioone, mis ei vaja teenust TheService, siis see ei käivitu.

Et mitte kulutada aega TheService käivitamisele iga kord, kui tehniline kirjeldus muutub, saate arendusprotsessi käigus käivitada TheServicei käsitsi terminalis ja lihtsalt mitte välja lülitada. Kui vaja, saate selle ka IDE silumisrežiimis käivitada. Seejärel koostavad spetsifikatsioonid kõik, saadavad päringu teenusele, see peatub ja saate seda hõlpsalt siluda. See muudab TDD-lähenemise tõesti mugavaks.

Järeldus

Oleme seda seadistust kasutanud nüüd umbes aasta ja me pole sellega mingeid tõrkeid kogenud. Spetsifikatsioonid tulevad välja palju paremini loetavad kui üksuse testimine Go-is ja need ei sõltu teenuse sisemise ülesehituse tundmisest. Kui me peame teenuse mingil põhjusel teises keeles ümber kirjutama, ei pea me tehnilisi andmeid muutma. Ainult ümbrised, mida kasutatakse testiteenuse käivitamiseks erineva käsuga, tuleks ümber kirjutada.