Komponenttien testaus Reaktissa: mitä ja miten testataan Jestillä ja Enzymellä.

Tämän artikkelin reagoivien komponenttien testaamisesta on kirjoittanut Alona Pysarenko - Frontend Engineer Django Starsilla.
Lue alkuperäinen artikkeli Django Stars -blogista.

React-komponenttien testaaminen voi olla haastavaa aloittelijoille ja kokeneille kehittäjille, jotka ovat jo työskennelleet testien kanssa. Voi olla mielenkiintoista verrata omia lähestymistapojasi niihin, joita käytämme projektissamme. Kooditietokannan kattamiseksi sinun on tiedettävä, mitkä komponentit on testattava ja mitkä komponentit tarkalleen komponentissa on katettava.

Tämän artikkelin aikana käsittelen seuraavia aiheita:

  • Määritä komponenttien testausjärjestys projektirakenteen perusteella
  • Etsi mitä jättää pois testin kattavuudesta (mitä ei testata)
  • Tunnista tilannekuvatestauksen välttämättömyys
  • Määritä, mitä komponentti testataan ja missä järjestyksessä
  • Anna yksityiskohtaisia ​​mukautettuja koodiesimerkkejä

Artikkelissa vaaditaan, että sinulla on tietoa Jest- ja Enzyme-asetuksista. Tietoja asennuksesta ja kokoonpanosta löytyy helposti heidän virallisilta verkkosivuilta.

Oletetaan seuraava tapaus: Sinun on peitettävä projektikoodit testillä. Mistä aloitat ja mitä testin lopussa pitäisi saada? 100% testipeitto? Se on vertailuarvo, johon sinun pitäisi pyrkiä, mutta useimmissa tilanteissa et saa sitä.

Miksi? Koska kaikkia koodeja ei pitäisi testata. Selvitämme miksi ja mitä pitäisi jättää testien ulkopuolelle. Vieläkin, 100%: n testipeitto ei aina takaa komponentin täydellistä testausta. Ei myöskään ole takuuta siitä, että se ilmoittaa sinulle, jos jotain on muutettu. Älä yritä saavuttaa prosenttimääriä, vältä kirjoittamasta vääriä testejä ja yritä vain kadottaa tärkeimpien komponenttien yksityiskohdat.

Komponenttien testauksen oikean järjestyksen määritteleminen projektirakenteen perusteella

Keskustelemme tästä kysymyksestä projektirakenteen seuraavassa osassa:

Otin jaetun hakemiston, koska se on tärkein. Se koostuu komponenteista, joita käytetään projektin useilla eri sivuilla. Ne ovat uudelleenkäytettäviä, ja yleensä ne ovat pieniä eikä monimutkaisia. Jos yksi tai toinen komponentti vikaantuu, se aiheuttaa toimintahäiriön muissa paikoissa. Siksi meidän pitäisi olla varmoja siitä, onko ne kirjoitettu oikein. Tämän hakemiston rakenne on jaettu useisiin kansioihin, joista jokainen sisältää komponentteja.

Komponenttien testauksen oikean järjestyksen määrittäminen jaetussa hakemistossa:

  • Noudata aina sääntöä mennä yksinkertaisesta monimutkaiseksi. Analysoi jokainen hakemisto ja määritä, mitkä komponentit ovat riippumattomia - nimittäin niiden renderointi ei ole riippuvainen muista komponenteista. Ne ovat itse valmiita ja niitä voidaan käyttää erikseen yhtenä kokonaisuutena. Yllä olevasta rakenteesta se on lomake-kansion tulohakemisto. Se sisältää tulokomponentit redux-muotoihin, kuten TextInput, SelectInput, CheckboxInput, DateInput jne.
  • Seuraavaksi meidän on määriteltävä apukomponentit, joita käytetään usein sisääntulokomponenteissa, mutta jotka olisi testattava niistä erillään. Tämä on utils-hakemisto. Tämän kansion komponentit eivät ole monimutkaisia, mutta erittäin tärkeitä. Ne ovat usein uudelleenkäytettäviä ja auttavat toistuvissa toimissa.
  • Seuraava vaihe on määritellä, mitä komponentteja voidaan käyttää myös itsenäisesti. Ota ne testattavaksi, jos sellaista on. Rakenteeltamme se on widgetit, pienet komponentit, joilla on yksinkertaiset toiminnot. Ne ovat kolmas kohta testijonojonossa.
  • Lisäksi analysoi loput hakemistot ja määrittele monimutkaisemmat komponentit, joita voidaan käyttää itsenäisesti tai yhdessä muiden komponenttien kanssa. Se on tapauksessamme modaalihakemisto. Nämä komponentit selitetään yksityiskohtaisesti alla.
  • Monimutkaisimmat komponentit jätetään loppuun. Ne ovat tapaushakemisto ja kentät lomake-kansiosta. Kuinka määrität, mikä testataan ensin? Otan hakemiston, josta komponentteja on jo käytetty testatuissa komponenteissa. Siten hoc-hakemiston komponentti oli läsnä widget-komponentissa. Siksi tiedän jo, mihin tarkoitukseen tätä hakemistoa ja sen komponenttia käytetään.
  • Viimeinen on kentät-kansio. Se sisältää komponentit, jotka on liitetty redux-muotoihin.

Lopullinen komponenttitilaus (esimerkkimme perusteella) näyttää tältä:

Tämän järjestyksen seurauksena lisäät testattujen komponenttien monimutkaisuutta askel askeleelta. Siten, kun on kyse monimutkaisempien komponenttien käytöstä, tiedät jo pienimpien käyttäytymisen.

Älä ota testata esimerkiksi taulukkokenttää, jos et ole varma, kuinka testata tekstikenttä. Älä ota redux-lomakkeella koristeltuja komponentteja, jos et ole itse testannut lomakekenttää.

Ole johdonmukainen valintasi suhteen, älä ota mieleesi ensimmäistä komponenttia ja vaihda logiikkaa. Projektisi rakenne voi tietysti vaihdella. Sillä voi olla muita hakemistonimiä tai siinä voi olla lisäkomponentteja, toimintoja ja pelkistimiä, mutta komponenttien testausjärjestyksen määrittelylogiikka on sama.

Määritetään, mitä tulisi katkaista testin kattavuudesta:

  • Kolmansien osapuolien kirjastot. Älä testaa toisesta kirjastosta otettua toiminnallisuutta. Et ole vastuussa koodista. Ohita se tai jäljittele toteutusta, jos tarvitset sitä koodin testaamiseen.
  • Vakioita. Nimi puhuu puolestaan. Ne eivät ole muutettavissa. Ne ovat staattisen koodin sarjoja, joita ei ole tarkoitettu muuttamaan.
  • Sisäiset tyylit (jos käytät niitä komponentissa). Sisäisten tyylien testaamiseksi sinun on kopioitava objekti testissä olevien tyylien kanssa. Jos objektityylit muuttuvat, sinun on muutettava ne myös testissä. Älä kopioi komponentin koodia kokeissa. Et koskaan pidä mielessäsi muuttaa sitä kokeissa. Kollegasi ei myöskään koskaan ymmärrä, että päällekkäisyyksiä on tapahtunut. Useimmissa tapauksissa sisäiset tyylit eivät muuta komponentin käyttäytymistä, joten niitä ei pitäisi testata. Poikkeusta voi olla, jos tyylit muuttuvat dynaamisesti.
  • Asiat, jotka eivät liity testattuun komponenttiin. Ohita peittäminen testatuilla komponenteilla tuotuilla komponentteilla. Ole varovainen, jos se on kääritty toiseen. Älä testaa kääriä, analysoi ja testaa ne erikseen.

Joten miten kirjoitat testit? Yhdistän kaksi testaustapaa:

  • Yksittäiskuvan testaus
  • Komponenttilogiikkatestaus

Keskustelen niistä molemmista nyt.

Kuinka testata valokuvien avulla

Snapshot Testing on hyödyllinen testaustyökalu, jos haluat olla varma, että käyttöliittymä ei ole muuttunut. Kun kohtaat tämän testaustyökalun ensimmäistä kertaa, sinulla voi olla kysymyksiä organisoinnista ja tilannekuvien hallinnasta. Periaate on hyvin yksinkertainen, mutta valitettavasti sitä ei ole kuvattu missään täysin.

Vaihe 1. Kirjoita komponentin testi ja käytä odotuslohkossa .toMatchSnapshot () -menetelmää, joka luo itse tilannekuvan:

it ('render text text komponent', () => {
    const TextInputComponent = renderer.create (). toJSON ();
    odottaa (TextInputComponent) .toMatchSnapshot ();
});

Vaihe 2. Kun suoritat testin ensimmäistä kertaa yhdellä tasolla testin ohella, luodaan hakemisto nimeltä __snapshots__ automaattisen muodostustiedoston kanssa laajennuksella.snap.

Snapshot näyttää tältä:

// Jest Snapshot v1, https://goo.gl/fbAQLP
vie [`Render TextInput -komponentti oikein komponentti 1`] =`

`;

Vaihe 3. Työnnä tilannekuva arkistoon ja säilytä se testin mukana.

Jos komponentti on vaihdettu, sinun on vain päivitettävä tilannekuva -updateSnapshot -lipulla tai käytettävä lyhyt lomake u -merkkiä.

Joten tilannekuva luodaan - miten se toimii?

Tarkastellaan kahta tapausta:

1. Komponentti on muuttunut

  • Suorita testit
  • Uusi tilannekuva luodaan, sitä verrataan automaattisesti luomaan tilannekuvaan, joka on tallennettu hakemistoon __snapshots__
  • Testit epäonnistuivat, koska tilannekuva on erilainen

2. Komponentti ei ole muuttunut

  • Suorita testit
  • Uusi tilannekuva luodaan, sitä verrataan automaattisesti luomaan tilannekuvaan, joka on tallennettu hakemistoon __snapshots__
  • Testit läpäisivät, koska tilannekuva on identtinen

Kaikki on kunnossa, kun testaamme pientä komponenttia ilman logiikkaa (vain käyttöliittymän renderointi). Mutta kuten käytäntö osoittaa, todellisissa hankkeissa ei ole tällaisia ​​komponentteja. Jos niitä on, heitä on vähän.

Onko riittävästi valokuvia komponenttien täydelliseen testaamiseen?

Tärkeimmät ohjeet komponenttien testaamiseen

1. Yhdessä komponentissa tulisi olla vain yksi tilannekuva.

Jos yksi tilannekuva epäonnistuu, todennäköisesti myös muut epäonnistuvat. Älä luo ja säilytä joukko tarpeettomia tilannekuvia, jotka tukkivat tilan ja hämmentävät kehittäjiä, jotka lukevat testit sinun jälkeensi.

Tietenkin on poikkeuksia, kun joudut testaamaan komponentin käyttäytymistä kahdessa tilassa: esimerkiksi komponentin tilassa ennen ponnahdusikkunan avaamista ja avaamisen jälkeen.

Jopa tällainen muunnos voidaan kuitenkin korvata tällä: ensimmäinen testi tallentaa komponentin oletustilan ilman ponnahdusikkunaa, ja toinen testi simuloi tapahtumaa ja tarkistaa tietyn luokan läsnäolon. Tällä tavoin voit helposti ohittaa useiden valokuvien luomisen.

2. Testaa rekvisiitta

Yleensä jakaan rekvisiittien testauksen kahteen testiin:

  • Ensinnäkin, tarkista oletusarvojen renderointi. Kun komponentti renderoidaan, odotan arvon olevan yhtä suuri kuin defaultProps siinä tapauksessa, että tässä prop-oletuksessa on defaultProps.
  • Toiseksi, tarkista tukivirran mukautettu arvo. Asetan oman arvoni ja odotan sen saavan komponentin renderoinnin jälkeen.

3. Tietotyyppien testaaminen

Jotta voimme testata, minkä tyyppisiä tietoja rekvisiitta tulee tai millaista tietoa saadaan tiettyjen toimien jälkeen, voimme käyttää erityistä kirjasto jest-extension (Additional Jest -sovittimet), jolla on laajennettu ottelujoukko, joka puuttuu jest. Tämän kirjaston avulla tietotyyppien testaaminen on paljon helpompaa ja nautinnollisempaa.

Toisaalta propyyppien testaaminen on ristiriitainen kysymys. Jotkut kehittäjät voivat kiistää propyyppitestauksen, koska se on kolmannen osapuolen paketti, eikä sitä pitäisi testata. Vaadin silti komponenttien propyyppien testaamista, koska en testaa itse paketin toimivuutta. Sen sijaan varmistan vain, että profetyypit ovat oikein. Tietotyyppi on erittäin tärkeä ohjelmointiosa, joten sitä ei pitäisi ohittaa.

4. Tapahtumien testaus

Kun olet luonut tilannekuvan ja peittänyt rekvisiitta testillä, voit olla varma, että komponentti näyttää oikein. Mutta tämä ei riitä täydelliseen kattavuuteen, jos komponentissa on tapahtumia.

Voit tarkistaa tapahtuman useilla tavoilla. Yleisimmin käytettyjä ovat:

  • pilkkatapahtuma => simuloi sitä => odottaa tapahtumaa kutsuttiin
  • pilkkatapahtuma => simuloi tapahtumaa paramsilla => odottaa tapahtumaa kutsuttiin ohitetulla paramsiin
  • läpäistä tarvittavat rekvisiitta => render komponentti => simuloi tapahtumaa => odottaa tiettyä käyttäytymistä kutsutulle tapahtumalle

5. Testausolosuhteet

Hyvin usein sinulla voi olla ehdot tietyn luokan tuotosta, koodin tietyn osan tuottamiseksi, tarvittavien rekvisiittien siirtämiseksi jne. Älä unohda tätä, koska oletusarvoilla vain yksi haara läpäisee testin, kun taas toinen jättää testaamattomana.

Monimutkaisissa komponenteissa, joissa on laskelmia ja paljon olosuhteita, voit ohittaa joitakin haarat. Varmista, että testin kaikki koodin osat on katettu testien peittotyökalulla ja tarkista silmämääräisesti, mitkä haarat kuuluvat ja mitkä eivät.

6. Testaustila

Tilan tarkistamiseksi on useimmissa tapauksissa tarpeen kirjoittaa kaksi testiä:

  • Ensimmäinen tarkistaa nykyisen tilan.
  • Toinen tarkistaa tilan tapahtuman kutsumisen jälkeen. Render komponentti => kutsutoiminto suoraan testissä => tarkista kuinka tila on muuttunut. Komponentin funktioon kutsumiseksi täytyy hakea komponentin esiintymät ja kutsua vasta sen jälkeen sen menetelmät (esimerkki esitetään seuraavassa testissä).

Kun olet käynyt läpi tämän ohjeluettelon, komponentti peitetään 90 - 100%. Jään 10% erityistapauksiin, joita ei kuvattu artikkelissa, mutta joita voi esiintyä koodissa.

Esimerkkejä testauksesta

Siirrymme esimerkkeihin ja peitä komponentit kokeilla, kuten olemme kuvanneet yllä askel askeleelta.

1. Komponentin testaaminen lomakkeista / tuloista.

Ota yksi komponentti lomakkeiden / syöttöjen hakemistosta. Olkoon se DateInput.js, päivämääräkeräilykentän komponentti.

Testatun komponentin koodiluettelo: DateInput.js
Näyttää:

DateInput-komponentti käyttää kirjaston react-datepicker -sovellusta kahdella apuohjelmalla:

  • valueToDate (muuntaa arvon päivämäärään)
  • dateToValue (muuntaa päivämäärän arvoksi)

Paketti on tarkoitettu päivämäärän manipulointiin, ja PropTypes on tarkoitettu Reaktin rekvisiittausten tarkistamiseen.

Komponentin koodin mukaan näemme luettelon oletussovelluksista, jotka auttavat komponenttia renderoimaan:

const defaultProps = {
    inputClassName: 'input-custom',
    kuukauttaNäytetty: 1,
    dateFormat: 'PP.KK.VVVV',
    showMonthYearsDropdowns: false,
    minDate: hetki ()
};

Kaikki rekvisiitta on sopiva tilannekuvan luomiseen, paitsi yksi: minDate: moment (). momentti () antaa meille nykyisen päivämäärän joka kerta, kun suoritamme testiä, ja tilannekuva epäonnistuu, koska se tallentaa vanhentuneen päivämäärän. Ratkaisu on pilkata tätä arvoa:

const defaultProps = {
    minDate: hetki (0)
}

Tarvitsemme minDate prop jokaiseen renderoituun komponenttiin. Välttääksesi rekvisiittien päällekkäisyyksiä, luon HOC: n, joka vastaanottaa defaultProps: n ja palauttaa hienon komponentin:

tuo TestDateInput tiedostosta '../DateInput';
const DateInput = (rekvisiitta) =>
    ;

Älä unohda hetki-aikavyöhykettä, varsinkin jos testit suorittavat kehittäjät toisesta maasta eri aikavyöhykkeellä. He saavat pilkatun arvon, mutta aikavyöhykkeen siirtyessä. Ratkaisu on asettaa oletusaikavyöhyke:

const moment = vaadi.requireAktualinen ('hetki-aikavyöhyke') .tz.setDefault ('America / Los_Angeles')

Nyt päivämäärän syöttökomponentti on valmis testattavaksi:

1.Luo ensin tilannekuva:

it ('render date date komponent', ') => {
    const DateInputComponent = renderer.create () .JSON ();
    odottaa (DateInputComponent) .toMatchSnapshot ();
});

2.Tuki rekvisiitta:

Katso rekvisiitta läpi ja löydä tärkeät. Ensimmäinen testattava potkuri on showMonthYearsDropdowns. Jos sen arvoksi tulee totta, avattava kuukauden ja vuoden avattava valikko näytetään:

se ('tarkista kuukauden ja vuoden avattavat avattavat valinnat', () => {
    const rekvisiitta = {
            showMonthYearsDropdowns: totta
        },
        DateInputComponent = asennus ().find('.datepicker ');
    odottaa (DateInputComponent.hasClass ( 'reagoivat-datepicker piilotus kuukauden')). ​​toEqual (tosi);
});

Testaa nolla prop-arvo. Tämä tarkistus on tarpeen sen varmistamiseksi, että komponentti renderoidaan ilman määriteltyä arvoa:

it ('render date date input oikein nolla-arvolla', () => {
    const rekvisiitta = {
            arvo: nolla
        },
        DateInputComponent = asennus ();
    odottaa ((DateInputComponent) .prop ( 'arvo')). toEqual (nolla);
});

3.Käyttää arvon profyypit, päivämäärä odotetaan merkkijonona:

se ('tarkista arvotyyppi', () => {
    const rekvisiitta = {
            arvo: '10 .03.2018 '
        },
        DateInputComponent = asennus ();
    odottaa (DateInputComponent.prop ( 'arvo')). toBeString ();
});

4.Testitapahtumat:

Tarkista ensin onChange-tapahtuma.

  • pilkkaaMuuta takaisinsoittoa
  • render date date input komponentti
  • simuloi muutostapahtumaa uudella tavoitearvolla
  • ja tarkista lopuksi, että onChange-tapahtuma on kutsuttu uuteen arvoon.
se ('tarkista onChange-soittopyyntö', () => {
    const onChange = jest.fn (),
        rekvisiitta = {
            arvo: '20 .01.2018 ',
            OnChange
        },
        DateInputComponent = asennus ().find('input ');
    DateInputComponent.simulate ('muutos', {tavoite: {arvo: hetki ('2018-01-22')}});
    odottaa (OnChange) .toHaveBeenCalledWith ('22 .01.2018' );
});

Varmista seuraavaksi, että päivämäärämerkin ponnahdusikkuna avautuu napsauttamalla päiväysyöttöä. Tätä varten etsi päivämääräsyöttö => simuloi napsautustapahtumaa => ja odota ponnahdusikkunaa luokan .react-datepicker esiintyessä.

se ('tarkista DatePicker-ponnahdusikkuna auki', () => {
    const DateComponent = asennus (),
        dateInput = DateComponent.find ("input [type = 'text']");
    dateInput.simulate (klikkaa ');
    odottaa (DateComponent.find ( 'reagoida-datepicker')). toHaveLength (1);
});

Täysi testiluettelo: DateInput.test.js

2. Hyödyllisyystestaus:

Testatun apuohjelman koodiluettelo: valueToDate.js

Tämän apuohjelman tarkoituksena on muuttaa arvo päivämäärään mukautetulla muodolla.

Ensinnäkin, analysoidaan annettu apuohjelma ja määritetään testauksen päätapaukset:

  1. Tämän apuohjelman tarkoituksen mukaan se muuttaa arvoa, joten meidän on tarkistettava tämä arvo:
  • Jos arvoa ei ole määritelty: meidän on oltava varmoja siitä, että apuohjelma ei palauta poikkeusta (virhe).
  • Jos arvo on määritelty: meidän on tarkistettava, että apuohjelma palauttaa päivämäärän.

2. Palautetun arvon tulisi kuulua hetkeluokkaan. Siksi sen pitäisi olla hetken esimerkki.

3. Toinen argumentti on dateFormat. Aseta se vakiona ennen testejä. Siksi se välitetään jokaisessa testissä ja palautusarvo päivämäärämuodon mukaan. Pitäisikö meidän testata dateFormat erikseen? Luulen, että ei. Tämä argumentti on valinnainen - jos emme määritä päivämäärämuotoa, apuohjelma ei rikkoudu, ja se palauttaa päivämäärän vain oletusmuodossa. Se on hetkellinen työ, emme pitäisi testata kolmansien osapuolien kirjastoja. Kuten aiemmin mainitsin, meidän ei pitäisi unohtaa hetki-aikavyöhykettä; se on erittäin tärkeä kohta, etenkin eri aikavyöhykkeiden kehittäjille.

Otetaan koodi:

  1. Kirjoita testi ensimmäiselle tapaukselle. Kun meillä ei ole arvoa, se on tyhjä.
const-muoto = 'PP.MM.VVVV';
it ('render valueToDate -apuohjelma tyhjellä arvolla', () => {
    const arvo = valueToDate ('', muoto);
    odottaa (arvo) .toEqual (nolla);
});

2. Tarkista, onko arvo määritetty.

Const date = '21 .11.2015 ',
      muoto = 'PPM.VVVVV';
it ('render valueToDate -apuohjelma määritellyllä arvolla', () => {
    const arvo = valueToDate (päivämäärä, muoto);
    odottaa (arvo) .toEqual (hetki (päivämäärä, muoto));
});

3. Tarkista, kuuluuko arvo momenttiluokkaan.

Const date = '21 .11.2015 ',
    muoto = 'PP.MM.VVVV';
se ('tarkistusarvo on hetken esiintymä', () => {
    const arvo = valueToDate (päivämäärä, muoto);
    odottaa (hetken arvoesimerkki) .toBeTruthy ();
});

Koko testiluettelo: valueToDate.test.js

3. Widgetien testaus

Widgetien testaamiseksi otin kehruukomponentin.

Koodiluettelo testatulle widgetille: Spinner.js

Näyttää tältä:

Pyörittäjää ei vaadita selityksessä, koska melkein kaikissa Web-resursseissa on tämä komponentti.

Joten jos menemme kirjoittamaan testejä:

  1. Ensimmäinen askel - tilannekuvan luominen:
se ('renderöi Spinner-komponentti oikein', () => {
   const SpinnerComponent = kiinnitys ();
   odottaa (SpinnerComponent) .toMatchSnapshot ();
});

2. Tarvikkeiden testaaminen:

Ensinnäkin tarkastellaan oletusarvoista nimikettä ja tarkistetaan, esitetäänkö se oikein.

se ('tarkista prop otsikko oletuksena', () => {
 const SpinnerComponent = kiinnitys ();
    odottaa (SpinnerComponent.find ('p'). text ()). toEqual ('Please wait');
});

Sitten tarkistamme mukautetun otsikon. Meidän on tarkistettava, että se palauttaa oikein määritellyn prop. Katso koodi, otsikko on kääritty rawMarkup util -sovellukseen ja tulostetaan vaarallisestiSetInnerHTML-ominaisuuden avulla.

Koodilistaus rawMarkup util:

vie oletustoiminto rawMarkup (malli) {
    palauta {__html: malli};
}

Pitääkö meidän sisällyttää rawMarkup-testit kehruukomponenttiin? Ei, se on erillinen apuohjelma ja se tulisi testata erillään kehrästä. Meillä ei ole väliä miten se toimii - meidän on vain tiedettävä, että otsikkopalkki tuottaa oikean tuloksen.

Selvennys: Syy vaarallisestiSetInnerHTML-ominaisuuden käyttöön on seuraava. Sivustomme on monikielinen, josta käännösmarkkinointiryhmä vastaa. He voivat kääntää sen yksinkertaisesti sanasarjoilla tai jopa koristella HTML-tunnisteilla, kuten , , tai jopa viipaloida tekstiä luetteloilla

    ,
      . Emme tiedä varmasti, kuinka he kääntävät ja koristavat tekstiä. Meidän on vain esitettävä kaikki nämä asiat oikein.

      Yhdistin kaksi päätestitapausta yhdessä testissä:

      • palauta oikea räätälöity otsikko
      • renderöi otsikko oikein HTML-tunnisteilla
      it ('tarkista otsikon nimi html-tunnisteilla', () => {
          const rekvisiitta = {
                  otsikko: ' Odota '
              },
              SpinnerComponent = kiinnitys ();
          odottaa (SpinnerComponent.find ('p'). text ()). toEqual ('Please wait');
      });

      Ota seuraava ehdotuksen alaotsikko. Se on valinnainen, ja siksi siinä ei ole oletusasetusta, joten ohita vaihe oletusasennuksella ja testaa mukautettuja rekvisiitta:

      • Tarkista, että tekstitys tekstityksessä toistuu oikein:
      const rekvisiitta = {
              alaotsikko: 'jäljellä 1 minuutti'
          },
          SpinnerComponent = kiinnitys ();
      se ('render text'), () => {
          odottaa (SpinnerComponent.find ( 's'). at (1) .text ()). toEqual (props.subTitle);
      });

      Tiedämme, että tekstitys on valinnainen. Siksi meidän on tarkistettava, onko sitä suoritettu oletus rekvisiitteilla leikkausmerkintöjen mukaan. Tarkista vain tunnisteiden lukumäärä

      :

      se ('tarkista alaotsikkoa ei esitetä', () => {
        const SpinnerComponent = kiinnitys ();
          odottaa (SpinnerComponent.find ( 'p'). pituus) .toEqual (1);
      });

      3.Testaa potkurityypit:

      • Otsikkoprofiilin odotetaan olevan merkkijono:
      it ('tarkista otsikkotyypin nimi on merkkijono', () => {
          const rekvisiitta = {
                  otsikko: 'Odota'
              },
              SpinnerComponent = kiinnitys ();
          odottaa (SpinnerComponent.find ( 's'). tekstiä ()). toBeString ();
      });
      • Tekstityspotentiaalin odotetaan myös olevan merkkijono:
      const rekvisiitta = {
              alaotsikko: 'jäljellä 1 minuutti'
          },
          SpinnerComponent = kiinnitys ();
      se ('Tekstityksen tyyppi on merkkijono', () => {
          odottaa (SpinnerComponent.find ( 's'). at (1) .text ()). toBeString ();
      });

      Koko testilista: Spinner.test.js

      4. Modaalien testaus (ModalWrapper.js ja ModalTrigger.js)

      Näyttää:

      Kuinka testata modaalit

      Ensinnäkin haluan selittää, miten modaalit järjestetään projektiimme. Meillä on kaksi komponenttia: ModalWrapper.js ja ModalTrigger.js.

      ModalWrapper vastaa ponnahdusikkunoiden asettelusta. Se sisältää modaalikontin, painikkeen 'close', modaalin otsikon ja rungon.

      ModalTrigger vastaa modaalien käsittelystä. Se sisältää ModalWrapper-asettelun ja sisältää tapahtumia modaalin asettelun hallintaan (avoimet ja suljetut toiminnot).

      Menen jokaisen komponentin yli erikseen:

      1.Testatun komponentin koodiluettelo: ModalWrapper.js

      Otetaan koodi:

      Ensinnäkin, ModalWrapper vastaanottaa komponentin ja tuottaa sen sisälle. Ensinnäkin, tarkista, että ModalWrapper ei epäonnistu ilman komponenttia. Luo tilannekuva oletus-rekvisiitta:

      se ('ilman komponenttia', () => {
          const ModalWrapperComponent = matala ();
          odottaa (ModalWrapperComponent) .toMatchSnapshot ();
      });

      Seuraava vaihe on simuloida sen todellinen tila komponenttien renderoinnilla, joka on kuljettu rekvisiittien läpi:

      se ('komponentilla', () => {
         const rekvisiitta = {
                 komponentti: () => {}
              },
              ModalWrapperComponent = matala ();
          odottaa (ModalWrapperComponent) .toMatchSnapshot ();
      });

      Testaa rekvisiitta

      Mukautetun luokan nimen vastaanottaminen:

      se ('render oikean luokan nimi', () => {
          const rekvisiitta = {
                  modalClassName: 'mukautettu luokan nimi'
              },
              ModalWrapperComponent = matala ().find('Modal ');
              odottaa (ModalWrapperComponent.hasClass (tilaustyönä luokkansa name ')). toEqual (tosi);
      });

      Muokatun otsikon ehdotuksen vastaanottaminen:

      it ('render oikea otsikko', () => {
          const rekvisiitta = {
                 otsikko: 'modaalinen otsikko'
             },
             ModalWrapperComponent = matala ().find('ModalTitle ');
          odottaa (ModalWrapperComponent.props (). children) .toEqual ('Modal Title');
      });

      Oikean näytösoppaan vastaanottaminen:

      se ('tarkista prop-arvo', () => {
              const rekvisiitta = {
                     Näytä: totta
                 },
                 ModalWrapperComponent = matala ().find('Modal ');
              odottaa (ModalWrapperComponent.props (). esittävät) .toEqual (tosi);
          });

      Tyyppien testaaminen

      • Näyttelyn prop
      se ('tarkista potkurityyppi', () => {
          const rekvisiitta = {
                 Näytä: totta
              },
              ModalWrapperComponent = matala ().find('Modal ');
          odottaa (ModalWrapperComponent.props (). esittävät) .toBeBoolean ();
      });
      • OnHide prop
      it ('render onHide prop type'), () => {
          const rekvisiitta = {
                  onPiilota: () => {}
              },
              ModalWrapperComponent = matala ().find('Modal ');
          odottaa (ModalWrapperComponent.props (). onHide) .toBeFunction ();
      });
      • Komponenttien prop
      se ('render pareiz komponentti prop tyyppi', () => {
         const rekvisiitta = {
                 komponentti: () => {}
             },
             ModalWrapperComponent = asennus ();
         odottaa (ModalWrapperComponent.props (). komponentti) .toBeFunction ();
      });

      Koko testilista: ModalWrapper.test.js

      2.Testatun komponentin koodiluettelo: ModalTrigger.js

      Modaalinen kääre on peitetty testillä. Toinen osa kattaa modaalisen laukaisukomponentin.

      Komponenttien yleiskatsaus: se perustuu vaihdettavaan tilaan, joka osoittaa ModalWrapperin näkyvyyden. Jos vaihdetaan: väärä, ponnahdusikkuna on piilotettu, muuten se on näkyvissä. Toiminto avaa () avaa alaelementin ponnahdusikkunan. Napsautustapahtuma ja toiminto sulje () piilottaa ponnahdusikkunan ModalWrapper-sovelluksessa olevalle painikkeelle.

      Yksittäiskuvan luominen:

      se ('renderoi ModalTrigger-komponentti oikein', () => {
          const ModalTriggerComponent = matala ( 
      );     odottaa (ModalTriggerComponent) .toMatchSnapshot (); });

      Pitäisikö meidän testata ModalTrigger komponenttituotteiden renderoinnilla? Ei - koska komponentti renderoidaan ModalWrapper-komponentin sisällä. Se ei riipu testatusta komponentista. Sitä peitettiin jo ModalWrapper-testeissä.

      Testaa rekvisiitta:

      Meillä on yksi tukilapsia ja haluamme olla varmoja, että meillä on vain yksi lapsi.

      se ('varmista, että sinulla on vain yksi lapsi (ohjauselementti)', () => {
          odottaa (ModalTriggerComponent.findWhere (node ​​=> node.key () === 'modal-control'). pituus) .toEqual (1);
      });

      Tyyppien testaaminen:

      Lasten potkurin tulisi olla esine, joten tarkista tämä seuraavassa testissä:

      const ModalTriggerComponent = asennus ( 
      );
      se ('tarkista lasten potkutyyppi', () => {
            odottaa (ModalTriggerComponent.props (). lapset) .toBeObject ();
      });

      Tärkeä osa ModalTrigger-komponenttia on tilojen tarkistaminen.

      Meillä on kaksi tilaa:

      • Ponnahdusikkuna avataan. Tietääksemme, että modaali on avattu, meidän on tarkistettava sen tila. Soita tätä varten komponentin esiintymästä avoin toiminto ja odota, että tilassa kytketyn tulee olla totta.
      se ('tarkista, että modaali on avattu', () => {
          const tapahtuma = {
              prevenDefault: () => {},
              stopPropagation: () => {}
          };
          ModalTriggerComponent.instance (). Auki (tapahtuma);
          odottaa (ModalTriggerComponent.state (). toggled) .toBeTruthy ();
      });
      • Ponnahdusikkuna on suljettu. Se testataan päinvastoin, vaihtaman tilan tulee olla väärä.
      se ('tarkista, että modaali on kiinni', () => {
         ModalTriggerComponent.instance (). Sulje ();
         odottaa (ModalTriggerComponent.state (). toggled) .toBeFalsy ();
      });

      Täysi testiluettelo: ModalTrigger.test.js

      Nyt modaalit testataan täysin. Yksi neuvo toisistaan ​​riippuvien komponenttien testaamiseksi: katso ensin komponentit läpi ja kirjoita testisuunnitelma, määrittele, mitä sinun on testattava jokaisessa komponentissa, tarkista kunkin komponentin testitapaukset ja varmista, että et toista sama testitapaus molemmissa komponenteissa. Analysoi huolellisesti mahdolliset ja optimaaliset variantit testin peittoa varten.

      5. HOC-testaus (korkeamman asteen komponentti)

      Kaksi viimeistä osaa (HOC ja lomakekenttien testaus) on kytketty toisiinsa. Haluaisin kertoa teille, kuinka testata kentän asettelua sen HOC: n kanssa.

      Tässä selitys mitä BaseFieldLayout on, miksi tarvitsemme tätä komponenttia ja missä sitä käytetään:

      • BaseFieldLayout.js on kääre lomakkeen syöttökomponenteille, kuten TextInput, CheckboxInput, DateInput, SelectInput jne. Niiden nimet päättyvät -Input, koska käytämme redux-lomakepakettia ja nämä komponentit ovat syöttökomponentit redux-muodon logiikkaan.
      • Tarvitsemme BaseFieldLayout-muotoa lomakekenttäkomponenttien asettelun luomiseen, joka on tarran, työkaluvihjeiden, etuliitteiden (valuutta, neliömetrien lyhenteet jne.), Kuvakkeiden, virheiden ja niin edelleen tekeminen.
      • Käytämme sitä BaseFieldHOC.js-tiedossa käärimään inputComponent kentän asetteluun ja yhdistämällä sen redux-muotoon -komponentin avulla.

      Testatun komponentin koodiluettelo: BaseFieldHOC.js

      Se on HOC, joka vastaanottaa lomakkeen syöttökomponentin ja palauttaa komponentin, kytkettynä redux-muotoon.

      HOC: n analysointi:

      • Tämä komponentti vastaanottaa vain yhden prop, komponentin. Ensinnäkin minun on luotava tämä komponentti ja käärittävä se BaseFieldHOC-tiedostoon.
      • Seuraavaksi minun on koristettava kääritty HOC redux-muodolla, jotta kenttä saadaan yhteyteen redux-muotoon.
      • Muodosta tämä kenttä React Redux -komponentin sisällä, jotta myymälä on testattavan komponentin käytettävissä. Voit pilkata kauppaa tekemällä:
      const-kauppa = createStore (() => ({}));

      Nyt, ennen kutakin testiä, minun on tehtävä seuraava:

      anna BaseFieldHOCComponent;
      beforeEach (() => {
          const TextInput = () => {palauta 'tekstinsyöttö'; },
              BaseFieldHOCWrapper = BaseFieldHOC (TextInput),
              TextField = reduxForm ({muoto: 'testForm'}) (BaseFieldHOCWrapper);
          BaseFieldHOCComponent = renderer.create (
              
                  
              
          ) .ToJSON ();
      });

      Sen jälkeen komponentti on valmis testattavaksi:

      1. Luo tilannekuva:
      se ('renderoi komponentti oikein', () => {
          odottaa (BaseFieldHOCComponent) .toMatchSnapshot ();
      });

      2. Varmista, että syötetty komponentti on kääritty BaseFieldLayout-sovellukseen renderoinnin jälkeen:

      se ('tarkista, että syöttökomponentti on kääritty BaseFieldLayoutiin', () => {
          odottaa (BaseFieldHOCComponent.props.className) .toEqual (lomake-ryhmä);
      });

      Siinä kaikki, HOC on katettu. Monimutkaisin osa redux-muotoon liittyvien komponenttien testaamisessa on kentän valmistelu (korista redux-muodolla ja setup-kaupalla). Loppu on helppoa, noudata vain ohjeita eikä mitään muuta.

      Täysi testiluettelo: BaseFieldHOC.test.js

      6. Lomakkeiden / kenttien testaus

      Kenttä HOC peitetään testeillä, jotta voimme siirtyä BaseFieldLayout-komponenttiin.

      Testatun komponentin koodiluettelo: BaseFieldLayout.js

      Otetaan koodi BaseFieldLayout.js ja kirjoitetaan testit yllä olevien ohjeiden mukaisesti:

      1. Luo ensin tilannekuva.

      Tätä komponenttia ei hahmotella ilman defaultProps:

      • inputComponent
      • Rexx-muodon tarjoamat rekvisiitta: syöttö- ja metaobjektit. Syöttö ominaisuuden nimellä ja meta, jossa ominaisuusvirhe ja kosketus:
      const defaultProps = {
         meta: {
              kosketti: nolla,
              virhe: nolla
          },
          panos: {
              nimi: 'kenttä-nimi'
          },
          inputComponent: () => {palauta 'testitapaus'; }
      }

      Jos haluat käyttää defaultProps-sovelluksia jokaisessa testatussa kääreessä, toimi seuraavasti:

      tuo TestBaseFieldLayout '../BaseFieldLayoutista';
      const BaseFieldLayout = (rekvisiitta) => ;

      Nyt olemme valmiita luomaan tilannekuvan:

      se ('renderoi BaseFieldLayout-komponentti oikein', () => {
          const BaseFieldLayoutComponent = renderer.create () .JJS ();
          odottaa (BaseFieldLayoutComponent) .toMatchSnapshot ();
      });

      2. Tarvikkeiden testaaminen:

      Tässä komponentissa on monia rekvisiitta. Näytän esimerkkejä useista, ja loput testataan analogisesti.

      • Varmista, että kuvaketuki esitetään oikein
      it ('render icon icon prop', () => {
          const rekvisiitta = {
                  kuvake: 
              },
              BaseFieldLayoutComponent = asennus ();
              odottaa (BaseFieldLayoutComponent.find (span). hasClass ( 'ikoni-huudahdus')). toBeTruthy ();
      });
      • Varmista, että työkaluvinkin sisältö näkyy tarran vieressä
      const rekvisiitta = {
              labelTooltipContent: 'etiketin työkaluvinkki'
          },
          BaseFieldLayoutComponent = asennus ();
      se ('tarkista potkuri on suoritettu', () => {
         odottaa (BaseFieldLayoutComponent.find (span). hasClass (tooltip-ikoni ")). toBeTruthy ();
      });
      • Testaus fieldLink prop
      • Varmista, että fieldLink on oletuksena tyhjä
      se ('tarkista potkuri on oletuksena nolla', () => {
          const BaseFieldLayoutComponent = matala ();
          odottaa (BaseFieldLayoutComponent.props (). fieldLink) .toBe (nolla);
      });
      • Varmista, että fieldLink näyttää oikein mukautetulla arvolla

      3. Testausvirheet:

      se ('tarkista, onko kentässä virhe', () => {
          const rekvisiitta = {
                  meta: {
                      kosketti: totta,
                      virhe: 'Tämä kenttä vaaditaan'
                  }
              },
              BaseFieldLayoutComponent = asennus ();
          odottaa (BaseFieldLayoutComponent.find ( '. virhe)). toHaveLength (1);
      });

      Täydellinen testiluettelo: BaseFieldLayout.test.js

      Bottom Line

      Nyt tiedät kuinka suorittaa komponenttien täydellinen kattavuustestaus projektirakenteen perusteella. Yritin omasta kokemuksestani selittää, mitä on tarpeen testata, missä järjestyksessä ja mitä voit jättää pois testin kattavuudesta. Esitin myös esimerkkejä useista testauskomponenteista ja havaitsin koodipohjan peittojärjestyksen.

      Toivon, että löydät tästä artikkelista hyödyllisen ja jaat vastauksesi. Kiitos, että luit.

      Jos pidät tätä viestiä hyödyllisenä, napauta alla olevaa -painiketta :)