Kuidas luua TDD ja React Testing Library abil tugevaid Reacti rakendusi?

“Paar ananassi kõrvuti rannas.” Pineapple Supply Co. saidil Unsplash

Üks asi, millega Reacti õppima asumisega hädas olin, oli minu veebirakenduste testimine nii kasulikul kui ka intuitiivsel viisil. Kasutasin ensüümi koos Jestiga komponendi pinnapealseks renderdamiseks iga kord, kui tahtsin seda testida.

Muidugi kuritarvitasin absoluutselt hetktõmmise testimise funktsiooni.

Noh, vähemalt kirjutasin testi, eks?

Võib-olla olete kuskilt kuulnud, et kirjutamisüksus ja integratsioonitestid parandavad teie kirjutatava tarkvara kvaliteeti. Halbade testide omamine tekitab seevastu väära enesekindlust.

Hiljuti osalesin Kent C. Doddsiga workshop.me kaudu töötoas, kus ta õpetas meile, kuidas kirjutada paremaid integratsioonitestiid Reacti rakendustele.

Samuti meelitas ta meid kasutama oma uut testimiskogu, eelistades rakenduse testimist samal viisil, nagu kasutaja sellega kokku puutub.

Selles artiklis õpime kasutama TDD-d, et luua kindlad Reacti rakendused, luues kommentaaride voo. Muidugi, see protsess kehtib peaaegu kogu tarkvara arendamise kohta, mitte ainult Reacti või JavaScripti rakenduste kohta.

Alustamine

Alustame rakenduse loo-reageeri-rakenduse käivitamise ja sõltuvuste installimisega. Minu eeldus on, et kui loete artiklit rakenduste testimise kohta, olete tõenäoliselt JavaScripti projektide installimise ja käivitamisega tuttav. Ma kasutan siin pigem lõnga kui npm.

loo-reageeri-rakenduse kommentaari voog
CD kommentaaride voog
lõnga

Praegusel kujul võime eemaldada kõik src-kataloogis olevad failid, välja arvatud register.js. Seejärel looge otse src-kausta sees uus kaust nimega komponendid ja teine ​​kaust nimega konteinerid.

Utiliitide testimiseks kavatsen selle rakenduse ehitada Kenti reaalajas testimiskogu kasutades. See on kerge testimise utiliit, mis julgustab arendajat nende rakendusi testima samamoodi, nagu seda kasutatakse.

Nagu ensüüm, ekspordib see renderdusfunktsiooni, kuid see renderdusfunktsioon ühendab teie komponendi alati täielikult. See ekspordib abimeetodeid, mis võimaldab teil elemente sildi või teksti järgi tuvastada või isegi ID-sid testida. Ensüüm teeb seda sama hästi oma mount API-ga, kuid selle loodud abstraktsioon pakub tegelikult rohkem võimalusi, millest paljud võimaldavad teil eemalduda rakenduse üksikasjade testimisest.

Me ei soovi enam rakenduse üksikasju testida. Tahame komponendi renderdada ja vaadata, kas UI-l millelegi klõpsates või seda muutes juhtuvad õiged asjad. See selleks! Enam pole vaja rekvisiite ega osariikide või klasside nimesid kontrollida.

Paigaldame need ja lähme tööle.

lõnga lisada reageerimise-testimise raamatukogu

Kommentaaride voo koostamine TDD-ga

Teeme selle esimese komponendi TDD-stiilis. Tulista oma testjooksja üles.

lõngaproov --kell

Konteinerite kausta lisame faili nimega CommentFeed.js. Selle kõrval lisage fail nimega CommentFeed.test.js. Juba esimese testi jaoks kontrolligem, kas kasutajad saavad kommentaare luua. Liiga vara? Olgu, kuna meil pole veel koodi, alustame väiksema testiga. Kontrollime, kas saame voo renderdada.

Mõned märkused reageerimise testimise raamatukogu kohta

Esiteks pangem tähele renderdusfunktsiooni siin. See sarnaneb sellega, kuidas reageeriv dom muudab komponendi DOM-ile, kuid tagastab objekti, mille võime hävitada, et saada korralikke testi abilisi. Sel juhul saame queryByText, mis annab mõne HTML-i teksti tagasi, arvestades mõnda teksti, mida me eeldame DOM-is nähtavat.

React Testing Library dokumentidel on hierarhia, mis peaks aitama teil otsustada, millist päringut või meetodit kasutada. Üldiselt läheb tellimus järgmiselt:

  • getByLabelText (vormi sisendid)
  • getByPlaceholderText (ainult siis, kui teie sisendil pole silti - vähem juurdepääsetav!)
  • getByText (nupud ja päised)
  • getByAltText (pildid)
  • getByTestId (kasutage seda näiteks dünaamilise teksti või muul viisil veider elementide jaoks, mida soovite testida)

Kõigil neil on seotud päringByFoo, mis teeb sama, välja arvatud juhul, kui see ei leia elementi, see ei suuda teie testi läbi kukkuda. Kasutage neid, kui proovite lihtsalt elemendi olemasolu kontrollida.

Kui ükski neist ei anna teile täpselt seda, mida otsite, tagastab renderdusmeetod ka konteineri atribuudile kaardistatud DOM-i elemendi, nii et saate seda kasutada nagu container.querySelector ('body # root').

Esimene rakenduseeskiri

Nüüd näeb rakendamine välja üsna lihtne. Peame lihtsalt veenduma, et komponendis on kommentaaride voog.

See võib olla hullem - ma mõtlesin, et hakkasin komponentide kujundamise ajal kirjutama kogu seda artiklit. Õnneks ei huvita testid liiga palju stiile, seega saame keskenduda oma rakenduse loogikale.

Järgmise testiga kontrollitakse, kas saame kommentaare anda. Kuid meil pole isegi ühtegi kommentaari, nii et lisame ka selle komponendi. Pärast testi küll.

Kavatsen luua ka rekvisiidiobjekti andmete salvestamiseks, mida võime nendes testides uuesti kasutada.

Sel juhul kontrollin, kas kommentaaride arv on võrdne kommentaaride etteantud üksuste arvuga. See on triviaalne, kuid testi ebaõnnestumine annab meile võimaluse luua fail Comment.js.

See roheline tuli süttib meie testkomplekti, et saaksime ilma hirmuta edasi liikuda. Kõik rahe TDD, meie omamoodi päästja. See töötab siis, kui anname sellele muidugi tühja massiivi. Aga mis siis, kui anname sellele reaalseid objekte?

Peame oma rakendusi värskendama, et asju tegelikult renderdada. Piisavalt lihtne nüüd, kui teate, kuhu me läheme, eks?

Ah jaa, meie test on jällegi möödas. Siin on ilus pilt selle ilust.

Pange tähele, kuidas ma kunagi ütlesin, et peaksime oma programmi lõnga käivitama? Hoiame seda mõnda aega nii. Asi on selles, et peate koodi mõistma.

Stiil on just see, mis on väljastpoolt - loeb vaid see, mis on sisemuses.

Igaks juhuks, kui soovite rakenduse käivitada, värskendage index.js järgmiselt:

Lisage kommentaari vorm

Siit hakkavad asjad lõbusamaks minema. Siit jõuame DOM-sõlmede unise kontrollimise juurest reaalse asjade tegemiseni ja käitumise kinnitamiseni. Kõik see muu kraam oli soojendus.

Alustame kirjeldusega, mida ma sellest vormist tahan. See peaks:

  • sisaldavad autori jaoks tekstisisestust
  • sisaldavad tekstisisestust enda kommenteerimiseks
  • saada nupp
  • helistage lõpuks API-le või mis tahes teenusele, mis tegeleb kommentaari loomise ja salvestamisega.

Saame selle nimekirja ühe integratsioonitesti abil maha võtta. Eelmiste testijuhtumite jaoks võtsime seda üsna aeglaselt, kuid nüüd hakkame kiirendama tempot ja proovima seda ühe hooga naelutada.

Pange tähele, kuidas meie testikomplekt areneb? Läksime kõvasti kodeerivast rekvisiidist nende endi katsejuhtumite sees, et luua neile tehas.

Korraldage, tegutsege, kinnitage

See järgnev integratsioonitesti võib jagada kolmeks osaks: korraldada, tegutseda ja kinnitada.

  • Korraldamine: prooviülesande jaoks rekvisiitide ja muude kinnituste loomine
  • Toimimine: simuleerige muudatusi sellistes elementides nagu tekstisisestused või nupuvajutused
  • Väide: kinnitage, et soovitud funktsioone käivitati õige mitu korda ja õigete argumentidega

Koodi kohta on tehtud mõned eeldused, nagu näiteks meie siltide nimetamine või asjaolu, et meil on loodud loovkommentaar.

Sisendite otsimisel tahame proovida leida neid nende siltide järgi. See tähtsustab juurdepääsu rakenduste loomisel juurdepääsetavusele. Lihtsaim viis vormi haarata on konteiner.querySelector abil.

Järgmisena peame määrama sisenditele uued väärtused ja simuleerima muutust, et värskendada nende olekut. See samm võib tunduda pisut kummaline, kuna tavaliselt kirjutame ühe tähe korraga, värskendades komponendi olekut iga uue tähemärgi jaoks.

See test käitub rohkem nagu kopeerimise / kleepimise käitumine, minnes tühjalt stringilt Socrates'i. Praegu pole ühtegi murettekitavat küsimust, kuid võib-olla tahame seda tähele panna, kui see hiljem ilmub.

Pärast vormi esitamist võime esitada väiteid näiteks selle kohta, millistele rekvisiitidele tugineti ja milliste argumentidega. Seda hetke saaksime kasutada ka vormi sisendite tühjendamise kontrollimiseks.

Kas see on hirmutav? Pole vaja karta, mu laps, kõndige seda teed. Alustage vormi lisamisega renderdusfunktsioonile.

Ma võiksin selle vormi eraldada omaette komponendiks, kuid hoidun praegu sellest. Selle asemel lisan selle oma loendisse “Refactor Wish List”, mida hoian oma laua kõrval.

See on TDD viis. Kui tundub, et midagi saab uuesti kujundada, tehke sellele märkus ja liikuge edasi. Refaktor ainult siis, kui abstraktsiooni olemasolu on teile kasulik ega tunne end asjatuna.

Kas mäletate, kui me oma testkomplekti uuesti kujundasime, luues tehase createProps? Täpselt nii. Saame ka refaktoritestid teha.

Nüüd lisame klassi meetodid käepideme muutmise ja käitlemise esitamise juurde. Neid vallandatakse, kui muudame sisendit või esitame vormi. Initsialiseerin ka meie riigi.

Ja see tegi seda. Meie testid mööduvad ja meil on midagi, mis sarnaneb tõelise rakendusega. Kuidas meie leviala välja näeb?

Pole paha. Kui ignoreerime kõiki index.js-s sisenevaid seadistusi, on meil täidetud ridade jaoks täielikult kaetud veebirakendus.

Muidugi, on ka teisi juhtumeid, mida tahame testida, et veenduda, kas rakendus töötab nagu me kavatseme. See katvusnumber on lihtsalt midagi, mille ülemuse üle saate kihlata, kui nad teiste kohortidega räägivad.

Meeldivad kommentaarid

Kuidas me kontrollime, kas meile kommentaar meeldib? See võib olla sobiv aeg meie rakenduses mõne autentimiskontseptsiooni loomiseks. Kuid me ei hüppa veel liiga kaugele. Uuendame kõigepealt meie rekvisiitide tehast, et lisada genereeritud kommentaaridele autentimisväli koos ID-dega.

Autenditud kasutaja autoriõigused antakse rakenduse kaudu edasi. Märgitakse kõik toimingud, mis on olulised nende autentimise osas.

Paljudes rakendustes võib see atribuut sisaldada mingisugust pääsuluba või küpsist, mis saadetakse serverile päringuid tehes.

Kliendi puhul annab selle omaduse olemasolu rakendusele teada, et ta saab lasta kasutajal vaadata oma profiili või muid kaitstud marsruute.

Selles testimisnäites ei hakka me autentimisega siiski eriti vaeva nägema. Kujutage ette sellist stsenaariumi: Jututuba sisenedes annate oma varjunime. Sellest hetkest alates vastutate iga kommentaari eest, mis seda ekraaninime kasutab, hoolimata sellest, kes selle nimega veel sisse loginud.

Ehkki see pole suurepärane lahendus, on isegi selles väljamõeldud näites mureks vaid testimine, kas komponent CommentFeed käitub nii nagu peab. Me ei muretse selle pärast, kuidas meie kasutajad sisse logitakse.

Teisisõnu, meil võib olla täiesti erinev sisselogimiskomponent, mis tegeleb konkreetse kasutaja autentimisega, saates nad seega tule ja raevu kaudu, et saada kõikvõimas autoriomadus, mis laseb neil meie rakenduses hävitada.

Kommenteerime "meeldib". Lisage see järgmine proovijuht ja värskendage siis rekvisiitide tehast, et lisada likeComment.

Ja nüüd rakenduse jaoks, alustame kommentaarikomponendi värskendamist, et sellel oleks meeldimisnupp ja ka andmetega atribuut, et saaksime selle leida.

Panin testi ID otse nupule, et saaksime sellele kohe klõpsu simuleerida, ilma et peaksime päringu valijaid pesastama. Lisasin nupule ka onClicki käitleja, nii et see kutsub üles sellele edastatud funktsiooni OnLike.

Nüüd lisame selle klassimeetodi lihtsalt meie kommentaariFeedi:

Võite küsida, miks me ei edasta likeCommendi prop lihtsalt kommentaari komponendile. Miks me muudame selle klassi kinnisvaraks?

Kuna see on üsna lihtne, ei pea me seda abstraktsiooni üles ehitama. Tulevikus võime otsustada lisada muud onClicki töötlejad, kes tegelevad näiteks analüüsiüritustega või algatavad selle postituse tulevaste kommentaaride tellimise.

Selle mahukomponendi käepideme meetodil mitme eri funktsioonikõne komplekteerimisel on oma eelised. Saame seda meetodit kasutada ka komponendi oleku värskendamiseks pärast edukat “Meeldib”, kui nii otsustame.

Ei meeldi kommentaarid

Sel hetkel on meil töötavad testid kommentaaride esitamiseks, loomiseks ja meeldimiseks. Muidugi, me ei ole rakendanud loogikat, mis seda tegelikult teeb - me ei värskenda poodi ega kirjuta andmebaasi.

Samuti võite märgata, et meie testitav loogika on habras ja pole reaalainete kommentaarivoo jaoks kohutavalt rakendatav. Näiteks mis juhtuks, kui prooviksime meeldida juba meile meeldinud kommentaarile? Kas see suurendab meeldimisi lõpmatuseni või erineb sellest? Kas mulle meeldivad minu enda kommentaarid?

Jätan komponentide funktsionaalsuse laiendamise teie kujutlusvõimele, kuid hea algus oleks uue katsejuhtumi kirjutamine. Siin on üks, mis rajaneb eeldusel, et tahaksime juba meeldinud kommentaari mittemeeldivaks muuta:

Pange tähele, et see meie koostatav kommentaaride voog võimaldab mulle oma kommentaaridele meeldida. Kes seda teeb?

Olen värskendanud kommentaari komponenti mõne loogika abil, et teha kindlaks, kas praegusele kasutajale kommentaar meeldis või mitte.

Noh, ma pettisin natuke: kus me viisime autorit varem onLike-funktsiooni juurde, vahetasin ma praeguse kasutajaga, mis on autentimisviis, mis edastati kommentaarikomponendile.

Lõppude lõpuks poleks mõistlik, kui kommentaari autor ilmub, kui kellelegi teisele nende kommentaar meeldib.

Sain sellest aru, kuna kirjutasin jõuliselt teste. Kui ma oleksin lihtsalt juhuslikult kodeerinud, võinuks see minust mööda minna, kuni üks mu töökaaslane mind teadmatuse pärast vaeva nägi!

Kuid siin pole teadmatust, on lihtsalt testid ja sellele järgnev kood. Uuendage kindlasti kommentaaride toite nii, et see loodaks autoriõiguse edasi anda. OnClicki töötlejate puhul ei saa autentimisõigust mööda lasta, kuna selle saab tuletada vanema käepideme sarnastest ja töötlemisviisidest sarnastest meetoditest.

Pakkimine üles

Loodetavasti näeb teie testikomplekt välja nagu valgustamata jõulupuu.

Sellel marsruudil on nii palju erinevaid teid, see võib pisut üle jõu käia. Iga kord, kui saate millegi kohta ideed, kirjutage see lihtsalt paberile või uude testplokki.

Näiteks öelge, et soovite tegelikult juurutada käepidet nagu käepide ja käepide nagu üks klassimeetod, kuid teil on praegu muud prioriteedid. Seda saate teha dokumenteerides sellisel juhul:

See ei tähenda, et peate kirjutama täiesti uue testi. Samuti võiksite värskendada kahte eelmist juhtumit. Kuid mõte on selles, et saate oma testjooksjat kasutada oma rakenduse jaoks hädavajalikuma ülesandeloendina.

Kasulikke linke

Seal on mõned suurepärased sisutükid, mis käsitlevad testimist laiemalt. Siin on mõned eriti inspireerivad seda artiklit, aga ka minu enda tavad.

  • Kent C. Dodds tutvustab Reacti testimisraamatukogu. Hea mõte on mõista selle testimisraamatukogu filosoofiat.
  • Kostis Kapelonise "Tarkvara testimine antimustrite kohta". Äärmiselt põhjalik artikkel, mis räägib üksuste ja integratsiooni testimisest. Samuti kuidas neid mitte teha.
  • Kent Becki "Test Driven Development by näide". See on TDD-mustreid käsitlev füüsiline raamat. See ei ole liiga pikk ja kirjutatud vestluslikult, muutes selle hõlpsaks seedimiseks.

Loodan, et see varjab teid mõneks ajaks.

Kas soovite rohkem postitusi või vaimukaid märkusi? Kui teile see artikkel meeldis, andke mulle mõned plaksutamised ja jälgige mind meediumites, Githubis ja Twitteris!