Kuinka rakentaa tukevia React-sovelluksia TDD: n ja React Testing Library -sovelluksen avulla

“Pari paria ananaksia vierekkäin rannalla.” Kirjoittanut Pineapple Supply Co. sivustolla Unsplash

Yksi asia, josta kamppailisin aloittaessani Reaktin oppimisen, oli verkkosovellusten testaaminen tavalla, joka on sekä hyödyllistä että intuitiivista. Käytin Enzymeä Jestin kanssa matalaan renderöintiin komponentti aina, kun halusin testata sitä.

Tietysti väärin tilannekuvien testausominaisuutta.

No, ainakin kirjoitin testin?

Olet ehkä kuullut jostain, että kirjoitusyksikkö ja integraatiotestit parantavat kirjoittamasi ohjelmiston laatua. Toisaalta huonojen testien seurauksena syntyy väärää luottamusta.

Kävin äskettäin workshop.me: n kautta workshopissa Kent C. Doddsin kanssa, jossa hän opetti meille, kuinka kirjoittaa parempia integraatiotestit React-sovelluksille.

Hän huijasi meitä myös käyttämään uutta testauskirjastoaan suosimaan sovelluksen testaamista samalla tavalla, kuin käyttäjä kohtaa sen.

Tässä artikkelissa opimme käyttämään TDD: tä rakentaakseen vakaita React-sovelluksia luomalla kommenttisyötteen. Tämä prosessi koskee tietysti melkein kaikkea ohjelmistokehitystä, ei vain React- tai JavaScript-sovelluksia.

Päästä alkuun

Aloitamme käynnistämällä luo-reagoi-sovellus ja asentamalla riippuvuudet. Oletan, että jos luet artikkeli sovellusten testaamisesta, olet todennäköisesti jo perehtynyt JavaScript-projektien asentamiseen ja käynnistämiseen. Käytän täällä lankaa pikemminkin kuin npm.

luo-reagoi -sovelluksen kommentti-syöte
CD-kommentti-syöte
lanka

Voimme poistaa kaikki src-hakemiston tiedostot paitsi index.js. Luo sitten heti src-kansion sisällä uusi kansio nimeltään komponentit ja toinen kansio nimeltään säilöt.

Apuohjelmien testaamiseksi aion rakentaa tämän sovelluksen Kentin React Testing Library -kirjaston avulla. Se on kevyt testi-apuohjelma, joka rohkaisee kehittäjää testaamaan sovelluksensa samalla tavalla kuin sitä käytetään.

Kuten Enzyme, se vie renderöintitoiminnon, mutta tämä renderöintitoiminto tekee aina täydellisen asennuksen komponentistasi. Se vie auttajamenetelmiä, joiden avulla voit paikantaa elementit tarran tai tekstin tai jopa testitunnusten avulla. Entsyymi tekee niin samoin kiinnitysliittymänsä kanssa, mutta sen luoma abstraktio tarjoaa todellakin enemmän vaihtoehtoja, joista monet antavat sinun päästä eroon käyttöönoton yksityiskohtien testaamisesta.

Emme halua enää testata käyttöönoton yksityiskohtia. Haluamme tuottaa komponentin ja nähdä, tapahtuvatko oikeat asiat, kun napsautamme tai muuttaa jotain käyttöliittymässä. Se siitä! Et enää tarkista rekvisiitta- tai osa- tai luokanimiä.

Asennetaan ne ja siirrytään töihin.

lanka lisää reakt-testaus-kirjasto

Kommenttisyötteen rakentaminen TDD: llä

Tehdään tämä ensimmäinen komponentti-TDD-tyyli. Tulipalo koekilpailijaasi.

lankatesti - kello

Konttikansioon lisätään tiedosto nimeltä CommentFeed.js. Lisää sen rinnalle tiedosto nimeltään CommentFeed.test.js. Varmistamme ensimmäisessä testissä, että käyttäjät voivat luoda kommentteja. Liian pian? Okei, koska meillä ei vielä ole koodia, aloitamme pienemmällä testillä. Tarkistetaan, että voimme tuottaa syötteen.

Jotkut huomautukset reagointi-testauskirjastoista

Huomaa ensin, että renderöintitoiminto on täällä. Se on samanlainen kuin tapa, jolla reagoi-dom tuottaa komponentin DOM: iin, mutta se palauttaa esineen, jonka voimme hajottaa saadakseen siistiä testiapuajia. Tässä tapauksessa saamme queryByText, joka palauttaa kyseisen HTML-elementin, kun otetaan huomioon jokin teksti, jonka odotamme näkevän DOM: lla.

React Testing Library -asiakirjoissa on hierarkia, jonka pitäisi auttaa sinua päättämään, mitä kyselyä tai hankintamenetelmää käytetään. Yleensä järjestys menee seuraavasti:

  • getByLabelText (lomaketulot)
  • getByPlaceholderText (vain jos syötölläsi ei ole tarraa - vähemmän saatavilla!)
  • getByText (painikkeet ja otsikot)
  • getByAltText (kuvat)
  • getByTestId (käytä tätä esimerkiksi dynaamiseen tekstiin tai muuten parittomiin elementteihin, jotka haluat testata)

Jokaiselle näistä on liitetty kyselyByFoo, joka tekee saman, paitsi että se ei läpäise testiäsi, kun se ei löydä elementtiä. Käytä näitä, jos vain testaat elementin olemassaoloa.

Jos mikään näistä ei anna sinulle tarkalleen sitä, mitä etsit, renderöintimenetelmä palauttaa myös säilöominaisuuteen kartoitetun DOM-elementin, joten voit käyttää sitä kuten container.querySelector ('body # root').

Ensimmäinen täytäntöönpanokoodi

Nyt toteutus näyttää melko yksinkertaiselta. Meidän on vain varmistettava, että ”Kommenttisyöte” on komponentissa.

Se voi olla pahempaa - tarkoitan, aioin kirjoittaa koko artikkelin muotoileessaan komponentteja. Onneksi testit eivät välitä liikaa tyyleistä, joten voimme keskittyä sovelluslogiikkaamme.

Seuraava testi varmistaa, että voimme tehdä kommentteja. Mutta meillä ei ole edes kommentteja, joten lisäämme myös tämän komponentin. Kokeen jälkeen kuitenkin.

Aion myös luoda rekvisiittaobjektin tallentaaksemme tietoja, joita voimme käyttää uudelleen näissä testeissä.

Tarkastelen tässä tapauksessa, että kommenttien lukumäärä on yhtä suuri kuin kommenttisyötteeseen välitettyjen kohteiden lukumäärä. Se on triviaalia, mutta testin epäonnistuminen antaa meille mahdollisuuden luoda kommentti.js-tiedosto.

Tämä vihreä valo syöttää testisarjamme, jotta voimme edetä ilman pelkoa. Kaikki rakeinen TDD, meidän tyyppinen pelastaja. Se toimii, kun annamme sille tietysti tyhjän ryhmän. Mutta entä jos annamme sille todellisia esineitä?

Meidän on päivitettävä toteutuksemme, jotta tosiasiallisesti tuotettaisiin. Tarpeeksi yksinkertainen nyt, että tiedät, mihin olemme menossa, eikö?

Voi katso, testi on jälleen kerran ohi. Tässä on siisti laukaus sen kauneudesta.

Huomaa, kuinka en koskaan sanonut, että meidän pitäisi käynnistää ohjelma lanka-aloituksella? Pidämme sitä tällä tavalla jonkin aikaa. Asia on, sinun on tunnettava koodi mielesi kanssa.

Muotoilu on juuri sitä, mikä on ulkopuolella - tärkeintä on sisäpuolella.

Päivitä index.js seuraaviin päivityksiin vain siinä tapauksessa, että haluat käynnistää sovelluksen:

Lisää kommenttilomake

Sieltä asiat alkavat olla hauskempia. Tässä siirrymme DOM-solmujen olemassaolon uneliaisesta tarkistamisesta tosiasiallisesti asioiden tekemiseen ja käyttäytymisen vahvistamiseen. Kaikki muut jutut olivat lämmittely.

Aloitetaan kuvaamalla mitä haluan tästä lomakkeesta. Sen pitäisi:

  • sisältävät kirjoittajan tekstinsyötön
  • sisältävät tekstinsyötön kommenttia varten
  • on lähetä-painike
  • soita lopulta sovellusliittymälle tai muille palveluille, jotka käsittelevät kommentin luomista ja tallentamista.

Voimme poistaa tämän luettelon yhdellä integraatiotestillä. Aikaisemmissa testitapauksissa otimme sen melko hitaasti, mutta nyt noutamme vauhtia ja yritämme naulata sen yhdellä rinteellä.

Huomaa, kuinka testisarjamme kehittyy? Siirryimme kovakoodaavien rekvisiittajien omien testitapausten sisällä tehtaan luomiseen heille.

Järjestä, toimi, väitä

Tämä seuraava integraatiotesti voidaan jakaa kolmeen osaan: järjestää, toimia ja puolustaa.

  • Järjestä: Luo rekvisiitta ja muut kiinnikkeet testitapaukseen
  • Toimi: simuloi elementtien, kuten tekstitulojen tai painikkeiden napsautuksien muutoksia
  • Väite: Vahvista, että haluttuihin toimintoihin on vedottu oikea määrä kertoja ja oikein perustein

Koodista on tehty joitain oletuksia, kuten tarrojemme nimeäminen tai se, että meillä on createComment-ehdotus.

Kun etsimme syötteitä, haluamme yrittää löytää ne niiden tarrojen perusteella. Tämä asettaa pääsyn etusijalle sovelluksia rakentaessamme. Helpoin tapa tarttua lomakkeeseen on container.querySelector.

Seuraavaksi meidän on annettava tuloille uudet arvot ja simuloitava muutos päivittääksesi niiden tilan. Tämä vaihe voi tuntua hieman omituiselta, koska yleensä kirjoitamme yhden merkin kerrallaan, päivittämällä komponentin tila jokaiselle uudelle merkille.

Tämä testi käyttäytyy enemmän kuin kopioinnin / liittämisen käyttäytyminen, siirtyen tyhjästä merkkijonosta Sokrates-merkinnäksi. Tällä hetkellä ei ole rikkovia ongelmia, mutta voimme ehkä kiinnittää huomion siihen, jos se ilmenee myöhemmin.

Kun lomake on toimitettu, voimme tehdä väitteitä esimerkiksi siitä, mihin rekvisiittaihin vedottiin ja millä perusteilla. Voimme myös käyttää tätä hetkeä varmistaaksemme, että lomakkeen syöttötiedot tyhjennetään.

Onko se pelottavaa? Ei tarvitse pelätä, lapseni, kävele tällä tavalla. Aloita lisäämällä lomake renderöintitoimintoosi.

Voisin hajottaa tämän muodon omaksi erilliseksi komponentiksi, mutta pidän nyt. Sen sijaan lisään sen ”Refactor Wish List” -luettelooni, jota pidän työpöydän vieressä.

Tämä on tapa TDD. Kun jotain näyttää siltä, ​​että se voidaan uudelleen muotoilla, tee se muistiin ja siirry eteenpäin. Refaktoria vain silloin, kun abstraktin läsnäolo on sinulle hyötyä eikä se tunne tarpeetonta.

Muistatko, kun uudistimme testipaketti luomalla createProps-tehtaan? Noin vain. Voimme myös refaktoritestit.

Otetaan nyt mukaan käsitellä ChangeChange ja handleSubmit luokkamenetelmät. Ne erotetaan, kun muutamme syöttöä tai lähetämme lomakkeen. Aion myös alustaa tilamme.

Ja se teki sen. Testimme läpäisevät ja meillä on jotain, joka muistuttaa todellista sovellusta. Kuinka kattavuutemme näyttää?

Ei paha. Jos sivuutamme kaikki index.js: n sisäiset asetukset, meillä on täysin katettu verkkosovellus suoritettujen rivien suhteen.

Tietenkin on todennäköisesti muita tapauksia, jotka haluamme testata varmistaaksemme, että sovellus toimii suunnitellusti. Tämä kattavuusnumero on vain jotain, jonka pomosi voi kerskata, kun he puhuvat muiden ryhmien kanssa.

Pidän kommentista

Entä jos tarkistamme, että voimme pitää kommentista? Tämä voi olla hyvä aika luoda jonkinlainen todennuksen käsite sovellukseemme. Mutta emme vielä hyppää vielä liian pitkälle. Päivitetään ensin rekvisiittatehtaamme lisätäksesi lupakentän ID-tunnusten kanssa luomiemme kommenttien kanssa.

Käyttäjälle, joka on todennettu, autden ominaisuus välitetään sovelluksen kautta. Kaikki toimenpiteet, joilla on merkitystä niiden todentamiselle, huomioidaan.

Monissa sovelluksissa tämä ominaisuus voi sisältää jonkinlaista käyttöoikeustunnusta tai evästettä, joka lähetetään, kun palvelimelle tehdään pyyntöjä.

Asiakkaassa tämän ominaisuuden läsnäolo antaa sovellukselle tietää, että hän voi antaa käyttäjän tarkastella profiiliaan tai muita suojattuja reittejä.

Tässä testiesimerkissä emme kuitenkaan viihdytä todennusta liian kovalla tavalla. Kuvittele seuraava tilanne: Kun kirjoitat chat-huoneen, annat näyttönimen. Siitä lähtien olet vastuussa jokaisesta kommenttia, joka käyttää tätä näyttönimeä, huolimatta siitä, kuka muu on kirjautunut sisään tällä nimellä.

Vaikka se ei ole hieno ratkaisu, edes tässä keksinnöllisessä esimerkissä olemme huolissamme vain testaamisesta, että CommentFeed-komponentti käyttäytyy niin kuin pitäisi. Emme ole kiinnostuneita siitä, kuinka käyttäjät ovat kirjautuneena sisään.

Toisin sanoen, meillä voi olla täysin erilainen kirjautumiskomponentti, joka käsittelee tietyn käyttäjän todennusta lähettämällä heille tulipalon ja raivon kautta, jotta saataisiin kaikkivaltias auth-ominaisuus, joka antaa heidän tuhota sovelluksessamme.

Otetaan "tykkää" kommentista. Lisää tämä seuraava testitapaus ja päivitä sitten rekvisiitehdas sisällyttämään likeComment.

Ja nyt toteutusta varten, aloitamme päivittämällä Kommentti-komponentin niin, että siinä on samankaltainen painike kuin myös tietojen osoittama ominaisuus, jotta voimme löytää sen.

Laitoin testitunnuksen suoraan painikkeeseen, jotta voimme heti simuloida napsautusta napsauttamatta kyselyn valitsijoita. Liitin myös painikkeeseen onClick-käsittelijän, jotta se kutsuu siihen siirrettyä onLike-toimintoa.

Nyt lisäämme vain tämän luokan menetelmän CommentFeed-tietokantaan:

Saatat ihmetellä, miksi emme siirrä vain likeComment-prop suoraan Kommentti-komponenttiin. Miksi teemme siitä luokkakiinteistön?

Koska se on melko yksinkertainen, meidän ei tarvitse rakentaa tätä abstraktiota. Jatkossa voimme päättää lisätä muita onClick-käsittelijöitä, jotka esimerkiksi käsittelevät analytiikkatapahtumia tai aloittavat tilauksen postin tuleviin kommentteihin.

Sillä, että kyetään niputtamaan useita erilaisia ​​toimintopuheluita tämän konttikomponentin käsittelevällä menetelmällä, on etunsa. Voisimme käyttää tätä menetelmää myös komponentin tilan päivittämiseen onnistuneen "Tykkää" -kohdan jälkeen, jos niin valitsemme.

Inhoavat kommentit

Tässä vaiheessa meillä on työskentelytestejä kommenttien esittämiseen, luomiseen ja pitämiseen. Emme tietenkään ole toteuttaneet logiikkaa, joka tosiasiallisesti tekee - emme päivitä kauppaa tai kirjoitamme tietokantaan.

Saatat myös huomata, että testaamamme logiikka on herkkä eikä sitä voida soveltaa kovinkaan tosielämän kommenttisyötteeseen. Entä esimerkiksi jos yrittäisimme pitää kommentista, josta pidimme jo? Kasvataanko tykkäyksiä määräämättömän ajan vai tuleeko siitä eroa? Voinko pitää omista kommentteistani?

Jätän komponenttien toiminnallisuuden laajentamisen mielikuvitukseesi, mutta hyvä alku olisi uuden testitapauksen kirjoittaminen. Tässä on yksi, joka perustuu oletukseen, että haluaisimme panna mielestämme jo pidämämme kommentin inhoamisen:

Huomaa, että tämän rakentamasi kommenttisyötteen avulla pidän omista kommentteistani. Kuka tekee sen?

Olen päivittänyt kommenttikomponentin jollain logiikalla sen määrittämiseksi, onko nykyinen käyttäjä pitänyt kommentista vai ei.

No huijain vähän: missä siirrimme tekijää onLike-toimintoon aiemmin, vaihdin nykyiseen käyttäjään, joka on lupaehdotus, joka siirrettiin Kommentti-komponenttiin.

Loppujen lopuksi ei olisi järkevää, että kommentin kirjoittaja ilmestyy, kun joku muu tykkää heidän kommentistaan.

Tajusin tämän, koska kirjoitin voimakkaasti testejä. Jos olisin vain koodannut sattumalta, se olisi voinut siirtyä ohi, kunnes yksi työtovereistani irrotti minua tietämättömyydestäni!

Mutta täällä ei ole tietämättömyyttä, vain testejä ja seuraavaa koodia. Muista päivittää CommentFeed niin, että se odottaa välittävän todennusominaisuuden. OnClick-käsittelijöille voimme jättää ohittamisen todennusominaisuuden ympäri, koska voimme päätellä sen vanhemman käsittelemästäLike- ja käsitelläDislike-menetelmistä johtuvasta todennusominaisuudesta.

Käärimistä

Toivottavasti testisarja näyttää kuin valaisematon joulukuusi.

Tässä on niin monia erilaisia ​​reittejä, joista voimme käydä hieman ylivoimaisia. Aina kun saat idean jostakin, kirjoita se vain joko paperille tai uuteen testilohkoon.

Sano esimerkiksi, että haluat tosiasiallisesti toteuttaa handleLike ja handleDislike yhdessä luokkamenetelmässä, mutta sinulla on tällä hetkellä muita prioriteetteja. Voit tehdä tämän dokumentoimalla esimerkiksi seuraavassa testitapauksessa:

Tämä ei tarkoita, että sinun on kirjoitettava kokonaan uusi testi. Voit myös päivittää kaksi edellistä tapausta. Mutta asia on, voit käyttää testijuoksijaasi pakottavammaksi tehtäväluetteloksi sovelluksellesi.

Hyödyllisiä linkkejä

Siellä on muutama hieno sisältökappale, joka käsittelee testaamista laajasti. Tässä on joitain erityisesti, jotka inspiroivat tätä artikkelia, samoin kuin omat käytännöt.

  • Kent C. Doddsin "Esittelyssä React-testikirjaston". On hyvä idea ymmärtää tämän testauskirjaston filosofiaa.
  • "Ohjelmistotestaus anti-malleista", kirjoittanut Kostis Kapelonis. Erittäin perusteellinen artikkeli, joka käsittelee yksikkö- ja integraatiotestausta sekä myös miten niitä ei tehdä.
  • Kent Beckin "Koeohjattu kehitys esimerkillä". Tämä on fyysinen kirja, joka käsittelee TDD-malleja. Se ei ole liian pitkä ja se on kirjoitettu keskustelullisesti, joten se on helppo sulauttaa.

Toivon, että se ohittaa sinut jonkin aikaa.

Kiinnostaako lisää viestejä tai nokkela huomautuksia? Jos pidit tästä artikkelista, anna minulle joitain claps ja seuraa minua Medium, Github ja Twitter!