Ispitivanje komponenti u React-u: što i kako testirati s Jest-om i Enzimom.

Ovaj članak o ispitivanju komponenata reakcija napisao je Alona Pysarenko - Frontend inženjer u tvrtki Django Stars.
Pročitajte originalni članak na blogu Django Stars.

Testing React komponente mogu biti izazovne početnicima, kao i iskusnim programerima koji su već radili s testovima. Možda će biti zanimljivo usporediti vlastite pristupe s onima koje koristimo u našem projektu. Da biste pokrili bazu kodova, morate znati koje komponente moraju biti testirane i koji kôd točno u komponenti treba biti obuhvaćen.

Tijekom ovog članka pokrit ću sljedeće teme:

  • Definirajte ispravan redoslijed ispitivanja komponenata na temelju strukture projekta
  • Pronađite što izostaviti u pokusu ispitivanja (što ne testirati)
  • Prepoznajte neophodnost testiranja snimka
  • Definirajte što treba testirati u komponenti i kojim redoslijedom
  • Navedite detaljne primjere prilagođenih kodova

Ovaj članak zahtijeva da imate znanje o postavljanju Jest-a i Enzima. Informacije o instalaciji i konfiguraciji mogu se lako naći na njihovim službenim web stranicama.

Pretpostavimo sljedeći slučaj: Morate pokriti projektnu bazu kodova pomoću testova. S čime treba započeti i što biste trebali dobiti na kraju testiranja? 100% pokrivenost testom? To je mjerilo kojem trebate težiti, ali u većini situacija to nećete dobiti.

Zašto? Jer ne biste trebali testirati sav kôd. Otkrit ćemo zašto i što treba izostaviti s testova. Čak štoviše, 100-postotna pokrivenost testom ne osigurava uvijek potpuno testiranje komponente. Također nema garancije da će vas obavijestiti ako je nešto promijenjeno. Ne težite postocima, izbjegavajte pisati lažne testove i samo pokušajte ne gubiti detalje glavnih komponenti.

Definiranje ispravnog redoslijeda ispitivanja komponenata na osnovu strukture projekta

Razgovarajmo o ovom pitanju u sljedećem dijelu strukture projekta:

Uzeo sam zajednički imenik, jer je najvažniji. Sastoji se od komponenti koje se koriste na nekoliko različitih stranica projekta. Ponovno se koriste i obično su mali i nisu složeni. Ako jedna ili druga komponenta ne uspije, to će uzrokovati neuspjeh na drugim mjestima. Zbog toga bismo trebali biti sigurni da li su napisane pravilno. Struktura ovog direktorija podijeljena je u nekoliko mapa, a svaka sadrži komponente.

Kako definirati ispravan redoslijed ispitivanja komponenata u zajedničkom direktoriju:

  • Uvijek slijedite pravilo prelaska od jednostavnog do složenog. Analizirajte svaki direktorij i definirajte koje su komponente neovisne - naime, njihovo prikazivanje ne ovisi o ostalim komponentama. Oni su samostalno dovršeni i mogu se koristiti zasebno kao jedna cjelina. Iz gornje strukture to je direktorij ulaza u mapi obrazaca. Sadrži ulazne komponente u redukcijske oblike, kao što su TextInput, SelectInput, CheckboxInput, DateInput, itd.
  • Zatim moramo definirati pomoćne komponente koje se često koriste u ulaznim komponentama, ali treba ih testirati osim njih. Ovo je direktorij utils. Komponente u ovoj mapi nisu komplicirane, ali su vrlo važne. Često ih se može ponovno upotrijebiti i pomažu u ponovljenim radnjama.
  • Sljedeći je korak definiranje koje se komponente mogu koristiti i neovisno. Ako ih ima, uzmite ih na testiranje. Iz naše strukture to su widgeti, male komponente sa jednostavnom funkcionalnošću. Bit će to treća stavka u redu za pokrivanje ispitivanja.
  • Nadalje, analizirajte ostatak direktorija i definirajte složenije komponente koje se mogu koristiti samostalno ili u kombinaciji s drugim komponentama. To je direktorij modaliteta u našem slučaju. Te će komponente biti detaljno objašnjene u nastavku.
  • Najsloženije komponente ostaju do kraja. Oni su hoc direktorij i polja iz mape obrazaca. Kako definirati koji treba prvo testirati? Uzimam imenik iz kojeg su komponente već korištene u testiranim komponentama. Tako je komponenta iz hoc direktorija bila prisutna u komponenti widgeta. Zato već znam gdje se i u koje svrhe koristi ovaj direktorij i njegova komponenta.
  • Posljednja je mapa polja. Sadrži komponente povezane sa redukcijskim oblicima.

Konačni poredak komponenti (na temelju našeg primjera) izgledat će ovako:

Slijedom ove naredbe, korak po korak povećavate složenost testiranih komponenti. Dakle, kada je u pitanju rad sa složenijim komponentama, već znate kako se ponašaju najmanji.

Ne uzimajte za testiranje, na primjer, polje 'niz', ako niste sigurni kako testirati 'tekst' polje. Ne uzimajte komponente ukrašene reduks-formom ako niste sami testirali polje "obrazac".

Budite dosljedni u svojim izborima, ne uzimajte prvu komponentu koja vam padne na pamet i prebacite logiku. Naravno, struktura vašeg projekta može se razlikovati. Može imati i druga imena direktorija ili može imati dodatne komponente, akcije i reduktore, ali logika definiranja redoslijeda testiranja komponenata je ista.

Definirajmo što treba izostaviti u pokusu ispitivanja:

  • Knjižnice trećih strana. Ne testirajte funkcionalnost preuzeta iz druge biblioteke. Vi niste odgovorni za taj kôd. Preskočite je ili imitirajte implementaciju ako vam treba za testiranje vašeg koda.
  • Konstante. Ime govori samo za sebe. Nisu promjenjivi. Oni su skupovi statičkog koda koji se ne žele mijenjati.
  • Inline stilovi (ako ih upotrebljavate u svojoj komponenti). Kako biste mogli testirati stilove inline, trebate duplicirati objekt sa stilovima vašeg testa. Ako se stilovi objekata promijene, morate ih promijeniti i u testu. Ne duplicirajte kôd komponente u testovima. Nikad ga nećete imati na umu da to mijenjate u testovima. Štoviše, vaš kolega nikada neće shvatiti da je došlo do dupliciranja. U većini slučajeva stilovi inline ne mijenjaju ponašanje komponente, tako da ih ne treba testirati. Može postojati iznimka ako se vaši stilovi dinamički mijenjaju.
  • Stvari koje nisu povezane s testiranom komponentom. Preskočite oblaganje testovima koji su uvezeni u ispitivanoj komponenti. Pazite ako je zamotan u drugu. Ne testirajte omot, samo ih analizirajte i odvojeno testirajte.

Pa kako zapravo pišete testove? Kombiniram dva pristupa testiranju:

  • Ispitivanje snimka
  • Logičko testiranje komponente

Sada ću razgovarati o njima oba.

Kako testirati snimkama

Snimanje testiranja koristan je alat za testiranje u slučaju da želite biti sigurni da se korisničko sučelje nije promijenilo. Kad se prvi put suočite s ovim alatom za testiranje, možda ćete imati pitanja koja se odnose na organizaciju i upravljanje snimkama. Princip je vrlo jednostavan, ali nažalost nije nigdje u potpunosti opisan.

Korak 1. Napišite test za komponentu i u bloku očekivanja koristite metodu .toMatchSnapshot () koja stvara Snimljeni snimak:

it ('ispravno prikaži tekstualnu komponentu', () => {
    const TextInputComponent = renderer.create (). toJSON ();
    očekivati ​​(TextInputComponent) .toMatchSnapshot ();
});

Korak 2. Kada prvi put pokrenete test na jednoj razini, zajedno s testom stvorit će se direktorij pod nazivom __snapshots__ s automatski generiranom datotekom iznutra s nastavkom.snap.

Snimka izgleda ovako:

// Jest Snapshot v1, https://goo.gl/fbAQLP
export [`Render TextInput ispravno komponenta 1`] =`

';

Korak 3. Gurnite snimku u spremište i spremite je zajedno s testom.

Ako je komponenta promijenjena, samo trebate ažurirati snimak s —updateSnapshot zastavom ili upotrijebiti kratku oznaku u zastavi.

Dakle, snimka je stvorena - kako to funkcionira?

Razmotrimo dva slučaja:

1. Komponenta se promijenila

  • Pokrenite testove
  • Stvara se novi snimak koji se uspoređuje s automatski generiranim snimkama pohranjenim u direktoriju __snapshots__
  • Testovi nisu uspjeli jer je snimka drugačija

2. Komponenta se nije promijenila

  • Pokrenite testove
  • Stvara se novi snimak koji se uspoređuje s automatski generiranim snimkama pohranjenim u direktoriju __snapshots__
  • Testovi su prošli jer je snimak identičan

Sve je u redu kad testiramo malu komponentu bez logike (samo prikazivanje UI-ja). Ali kao što pokazuje praksa, na stvarnim projektima nema tih komponenti. Ako postoje, malo ih je.

Ima li dovoljno snimaka za testiranje komponenti?

Glavne upute za ispitivanje komponenata

1. Jedna komponenta treba imati samo jedan snimak.

Ako jedna snimka ne uspije, najvjerojatnije će nedostajati i ostala. Ne stvarajte i ne spremajte gomilu nepotrebnih snimaka koji začepljuju prostor i zbunjuju programere koji će čitati vaše testove nakon vas.

Naravno, postoje izuzeci kada trebate testirati ponašanje komponente u dva stanja: na primjer, u stanju komponente prije otvaranja skočnog prozora i nakon otvaranja.

Međutim, čak se i takva varijanta može zamijeniti ovom: prvi test pohranjuje zadano stanje komponente bez skočnog prozora, a drugi test simulira događaj i provjerava prisutnost određene klase. Na taj način možete lako zaobići stvaranje nekoliko snimaka.

2. Ispitivanje rekvizita

U pravilu dijelim ispitivanje rekvizita na dva ispitivanja:

  • Prvo provjerite renderiranje zadanih vrijednosti prop. Kad se komponenta predstavi, očekujem da će vrijednost biti jednaka defaultProps u slučaju da ovaj prop ima defaultProps.
  • Drugo, provjerite prilagođenu vrijednost prop. Postavljam vlastitu vrijednost i očekujem da će ona biti primljena nakon prikazivanja komponente.

3. Ispitivanje vrsta podataka

Kako bismo testirali kakvu vrstu podataka dolazi u rekvizitima ili kakvu vrstu podataka dobivaju nakon određenih radnji, možemo upotrijebiti posebnu biblioteku vic-extension (Additional Jest matchers) koja ima prošireni skup podudarnosti koji izostaju u Jest. Pomoću ove biblioteke testiranje podataka je mnogo lakše i ugodnije.

Testiranje protipista, s druge strane, kontradiktorno je pitanje. Neki programeri mogu se suprotstaviti testiranju proptipova jer je to paket treće strane i ne bi ih trebalo testirati. Ipak, inzistiram na testiranju vrsta komponenti jer ne testiram samu funkcionalnost paketa. Umjesto toga, ja samo osiguravam da su propitivi ispravni. Vrsta podataka vrlo je važan programski dio i ne bi ga trebalo preskočiti.

4. Ispitivanje događaja

Nakon stvaranja snimke i pokrivanja rekvizita testovima, možete biti sigurni da će se komponenta ispravno prikazati. No to nije dovoljno za potpuno pokrivanje u slučaju da imate događaje u komponenti.

Događaj možete provjeriti na nekoliko načina. Najraširenije su:

  • izrugivati ​​događaj => simulirati ga => očekivan je događaj
  • mock event => simuliranje događaja paramsima => očekuje se događaj sa prolaznim paramsima
  • proći potrebne rekvizite => render komponenta => simulirati događaj => očekujte određeno ponašanje na pozvanom događaju

5. Uvjeti ispitivanja

Vrlo često možete imati uvjete za izlaz određene klase, prikaz određenog dijela koda, prijenos potrebnih rekvizita i tako dalje. Ne zaboravite na to, jer uz zadane vrijednosti, samo će jedna grana proći test, dok će druga ostati neprovjerena.

U složenim komponentama s izračunima i puno uvjeta možete propustiti neke grane. Da biste bili sigurni da su svi dijelovi koda obuhvaćeni testovima, upotrijebite alat za pokrivanje testa i vizualno provjerite koje su grane pokrivene, a koje nisu.

6. Stanje ispitivanja

Za provjeru stanja u većini slučajeva potrebno je napisati dva ispitivanja:

  • Prva provjerava trenutno stanje.
  • Drugi provjerava stanje nakon pozivanja na događaj. Render komponenta => funkcija poziva izravno u testu => provjerite kako se stanje promijenilo. Da biste pozvali funkciju komponente, morate dobiti instancu komponente i tek onda pozvati njezine metode (primjer je prikazan u sljedećem testu).

Nakon što prođete ovaj popis uputa, vaša će komponenta biti pokrivena od 90 do 100%. Ostavljam 10% za posebne slučajeve koji nisu opisani u članku, ali mogu se pojaviti u kodu.

Primjeri testiranja

Prijeđimo na primjere i pokrivamo komponente testovima kao što smo opisali gore, korak po korak.

1. Ispitivanje komponente iz obrazaca / ulaza.

Uzmite jednu komponentu iz direktorija obrazaca / ulaza. Neka bude DateInput.js, komponenta za polje za odabir datuma.

Popis kodova za testiranu komponentu: DateInput.js
Izgleda kao:

Komponenta DateInput koristi odazivač datuma reakcije knjižnice, s dvije uslužne programe:

  • valueToDate (pretvara vrijednost u datum)
  • dateToValue (pretvara datum u vrijednost)

Paket je za manipuliranje datumom, a PropTypes za provjeru React rekvizita.

Prema kodu komponente, možemo vidjeti popis zadanih rekvizita koji pomažu da se komponenta prikaže:

const defaultProps = {
    inputClassName: 'input-custom',
    mjesecipokazano: 1,
    dateFormat: 'DD.MM.YYYY',
    showMonthYearsDropdowns: false,
    minDatum: trenutak ()
};

Svi su rekviziti prikladni za stvaranje snimke, osim jednog: minDate: moment (). moment () dat će nam trenutni datum svaki put kada pokrenemo test i snimak neće uspjeti jer pohranjuje zastarjeli datum. Rješenje je ismijavanje ove vrijednosti:

const defaultProps = {
    minDatum: trenutak (0)
}

Potreban nam je minDate prop u svakoj izvedenoj komponenti. Da izbjegnem dupliciranje rekvizita, stvaram HOC koji prima defaultProps i vraća lijepu komponentu:

uvoz TestDateInput s '../DateInput';
const DateInput = (rekviziti) =>
    ;

Ne zaboravite na vremensku zonu, posebno ako će vaše testove izvoditi programeri iz druge zemlje u drugoj vremenskoj zoni. Oni će primiti izmiješanu vrijednost, ali s pomakom vremenske zone. Rješenje je postaviti zadanu vremensku zonu:

const moment = Requ.requireActual ('trenutak-vremenska zona'). tz.setDefault ('Amerika / Los_Angeles')

Sada je komponenta za unos datuma spremna za testiranje:

1.Stvorite najprije snimku:

it ('ispravno prikaži datumsku komponentu', () => {
    const DateInputComponent = renderer.create (). toJSON ();
    očekivati ​​(DateInputComponent) .toMatchSnapshot ();
});

2. Ispitivanje rekvizita:

Pogledajte kroz rekvizite i pronađite one važne. Prva podrška za testiranje su showMonthYearsDropdowns. Ako je postavljeno na true, prikazuje se padajući mjesec i godina:

it ('provjerite padajuće padajuće mjesece i godine', () => {
    const rekviziti = {
            showMonthYearsDropdowns: istina
        }
        DateInputComponent = mount ().find('.datepicker ');
    očekivati ​​(DateInputComponent.hasClass ( 'reagirati-datepicker skrivanje mjeseca')) toEqual (istina).
});

Ispitajte nultu vrijednost prop. Ova provjera potrebna je kako bi se osiguralo da se komponenta prikazuje bez definirane vrijednosti:

it ('prikaži datum datum ispravno s null vrijednosti', () => {
    const rekviziti = {
            vrijednost: null
        }
        DateInputComponent = mount ();
    očekivati ​​(() DateInputComponent .prop ( '') vrijednost) toEqual (null).
});

3.Test provjere za vrijednost, datum koji se očekuje kao string:

it ('provjeri vrstu vrijednosti', () => {
    const rekviziti = {
            vrijednost: '10 .03.2018 '
        }
        DateInputComponent = mount ();
    očekivati ​​(DateInputComponent.prop ( 'vrijednost')) toBeString ().
});

4.Test događanja:

Prvo provjerite događaj onChange.

  • izrugivanje naPromijeni povratni poziv
  • komponenta unosa datuma unosa
  • simuliraju događaj promjene s novom ciljnom vrijednošću
  • i na kraju provjerite je li onChange događaj pozvan s novom vrijednošću.
it ('provjeri onChange povratni poziv', () => {
    const onChange = jest.fn (),
        rekviziti = {
            vrijednost: '20 .01.2018 ',
            onChange
        }
        DateInputComponent = mount ().find('input ');
    DateInputComponent.simulate ('promjena', {target: {vrijednost: moment ('2018-01-22')}});
    očekivati ​​(onChange) .toHaveBeenCalledWith ('22 .01.2018' );
});

Zatim osigurajte da se skočni prozor za odabir datuma otvori nakon klika na datum. Za to pronađite datum unosa => simulirajte događaj klika => i očekujte skočni prozor kada je prisutan klas .react-datepicker.

it ('provjeri skočni prozor DatePicker otvoren', () => {
    const DateComponent = mount (),
        dateInput = DateComponent.find ("input [type = 'text']");
    dateInput.simulate ( 'klik');
    očekivati ​​(DateComponent.find () 'reagira-datepicker.') toHaveLength (1).
});

Potpuni popis testova: DateInput.test.js

2. Testiranje korisnosti:

Popis kodova za testirani program: valueToDate.js

Svrha ovog uslužnog programa je pretvaranje vrijednosti u datum s prilagođenim formatom.

Prije svega, analizirajmo uslužni program i definiramo glavne slučajeve za testiranje:

  1. Prema namjeni ovog uslužnog programa, on transformira vrijednost, tako da trebamo provjeriti ovu vrijednost:
  • U slučaju da vrijednost nije definirana: moramo biti sigurni da uslužni program neće vratiti izuzetak (grešku).
  • U slučaju da je definirana vrijednost: moramo provjeriti hoće li uslužni program vratiti datum.

2. Povratna vrijednost treba pripadati trenutnoj klasi. Zbog toga bi to trebala biti instanca trenutka.

3. Drugi argument je datumFormat. Postavite ga kao konstantno prije ispitivanja. Zbog toga će se proslijediti u svakom ispitivanju i vratiti vrijednost prema formatu datuma. Trebamo li testirati datumFormat odvojeno? Pretpostavljam da ne. Ovaj argument je neobavezan - ako ne postavimo datumFormat, uslužni program se neće pokvariti i jednostavno će vratiti datum u zadanom obliku. To je posao trenutka, ne bismo trebali testirati biblioteke trećih strana. Kao što sam već spomenuo, ne bismo trebali zaboraviti na vremensku zonu; To je vrlo važna točka, posebno za programere iz različitih vremenskih zona.

Kôd:

  1. Napišite test za prvi slučaj. Kad nemamo vrijednost, prazna je.
const format = 'DD.MM.YYYY';
it ('render valueToDate uslužni program s praznom vrijednošću', () => {
    const value = valueToDate ('', format);
    očekivati ​​(vrijednosti) .toEqual (nula);
});

2. Provjerite je li definirana vrijednost.

const date = '21 .11.2015. ',
      format = 'DD.MM.YYYY';
it ('render valueToDate uslužni program s definiranom vrijednošću', () => {
    const value = valueToDate (datum, format);
    očekivati ​​(vrijednost) .toEqual (trenutak (datum, format));
});

3. Provjerite pripada li vrijednost trenutnoj klasi.

const date = '21 .11.2015. ',
    format = 'DD.MM.YYYY';
it ('vrijednost provjere je instanceof moment', () => {
    const value = valueToDate (datum, format);
    ocekivati ​​(vrijednost instanceof moment) .toBeTruthy ();
});

Potpuni popis testova: valueToDate.test.js

3. Testiranje widgeta

Za testiranje widgeta uzeo sam spinner komponentu.

Popis koda za testirani widget: Spinner.js

Izgleda ovako:

Oglas nije potreban u objašnjenju, jer gotovo svi web resursi imaju ovu komponentu.

Pa ako krenemo pisati testove:

  1. Prvi korak - stvaranje snimke:
it ('ispravno prikaži komponentu Spinnera', () => {
   const SpinnerComponent = montirati ();
   očekivati ​​(SpinnerComponent) .toMatchSnapshot ();
});

2. Ispitivanje rekvizita:

Prvo pogledamo zadani naziv prop i provjeravamo je li pravilno prikazan.

it ('provjeri naslov propitacije prema zadanim postavkama', () => {
 const SpinnerComponent = montirati ();
    očekivati ​​(SpinnerComponent.find ('p'). text ()). toEqual ('Molimo pričekajte');
});

Zatim provjeravamo prilagođeni naslov prop. Moramo provjeriti vraća li ispravno definirani prop. Pogledajte kôd, naslov je zamotan u uslužni program rawMarkup i ispisuje se uz pomoć svojstva opasnoSetInnerHTML.

Popis kodova za uslužni program rawMarkup:

izvoz zadane funkcije rawMarkup (predložak) {
    povratak {__html: predložak};
}

Moramo li uključiti testove za rawMarkup u komponentu spinnera? Ne, to je poseban program i treba ga testirati osim kotača. Nije nam važno kako to funkcionira - samo trebamo znati da podupirač naslova vraća točan rezultat.

Pojašnjenje: Razlog korištenja svojstva opasnoSetInnerHTML je sljedeći. Naša je stranica višejezična, za koju je odgovoran tim za prijevod prevoditelja. Oni ga mogu prevesti jednostavno kombinacijom riječi ili čak ukrasiti HTML oznakama, poput , , ili čak narezati tekst sa popisima

    ,
      . Ne znamo sigurno kako oni prevode i ukrašavaju tekst. Trebamo ispravno prikazati sve te stvari.

      Kombinirao sam dva glavna testna slučaja u jednom testu:

      • vratiti ispravan prilagođeni naslov prop
      • ispravno prikazati naslov propitacije s HTML oznakama
      it ('provjerite naslov podrške s html oznakama', () => {
          const rekviziti = {
                  title: ' Molimo pričekajte '
              }
              SpinnerComponent = montirati ();
          očekivati ​​(SpinnerComponent.find ('p'). text ()). toEqual ('Molimo pričekajte');
      });

      Uzmi sljedeći potkateg. To je opcionalno i zato nema zadanu pomoćnu opremu, pa preskočite korak sa zadanim rekvizitima i testirajte prilagođene rekvizite:

      • Provjerite je li tekst u subTitle propuhu pravilno:
      const rekviziti = {
              podnaslov: 'lijeva 1 minuta'
          }
          SpinnerComponent = montirati ();
      it ('uzmite ispravan tekst', () => {
          očekivati ​​(SpinnerComponent.find ( 'p'), na (1) (.text)). toEqual (props.subTitle).
      });

      Znamo da je subTitle izborni. Zbog toga moramo provjeriti je li izveden sa zadanim rekvizitima, prema oznaci sječenja. Samo provjerite broj oznaka

      :

      it ('provjeri podnaslov nije prikazan', () => {
        const SpinnerComponent = montirati ();
          očekivati ​​(SpinnerComponent.find ( 'p') dužina). .toEqual (1);
      });

      3.Testiranje vrsta prop:

      • Za naslovnu potporu za koju se očekuje da će biti string:
      it ('tip provjere naslova je string', () => {
          const rekviziti = {
                  naslov: 'Čekaj'
              }
              SpinnerComponent = montirati ();
          očekivati ​​(SpinnerComponent.find ( 'p') tekst ().) toBeString ().
      });
      • Za subTitle prop takođe očekuje se string:
      const rekviziti = {
              podnaslov: 'lijeva 1 minuta'
          }
          SpinnerComponent = montirati ();
      it ('tip za subTitle je string', () => {
          očekivati ​​(SpinnerComponent.find ( 'p'), na (1) (.text)). toBeString ().
      });

      Potpuni popis testova: Spinner.test.js

      4. Testiranje modaliteta (ModalWrapper.js i ModalTrigger.js)

      Izgleda kao:

      Kako testirati modalitete

      Prije svega, želim objasniti kako se organiziraju modaliteti na našem projektu. Imamo dvije komponente: ModalWrapper.js i ModalTrigger.js.

      ModalWrapper je odgovoran za izgled skočnog prozora. Sadrži modalni spremnik, gumb "zatvori", naziv modula i tijelo.

      ModalTrigger je odgovoran za modalno rukovanje. Sadrži izgled ModalWrapper i sadrži događaje za kontrolu izgleda modela (radnje otvaranja i zatvaranja).

      Prijeći ću svaku komponentu zasebno:

      1.Code popis za testiranu komponentu: ModalWrapper.js

      Kôd:

      Prvo, ModalWrapper prima komponentu i prikazuje je unutra. Prije svega, provjerite da ModalWrapper neće uspjeti bez komponente. Napravite snimak sa zadanim rekvizitima:

      it ('bez komponente', () => {
          const ModalWrapperComponent = plitko ();
          očekivati ​​(ModalWrapperComponent) .toMatchSnapshot ();
      });

      Sljedeći je korak simuliranje stvarnog stanja s prikazom komponenti prošao kroz rekvizite:

      it ('s komponentom', () => {
         const rekviziti = {
                 komponenta: () => {}
              }
              ModalWrapperComponent = plitko ();
          očekivati ​​(ModalWrapperComponent) .toMatchSnapshot ();
      });

      Ispitivanje rekvizita

      Primanje podrške prilagođene klase:

      it ('uzmi ispravno ime klase', () => {
          const rekviziti = {
                  modalClassName: 'naziv prilagođene klase'
              }
              ModalWrapperComponent = plitko ().find('Modal ');
              očekivati ​​(ModalWrapperComponent.hasClass ( 'custom-klase-name')) toEqual (pravi).
      });

      Primanje prilagođene naslovne potpore:

      it ('dovedi ispravan naslov', () => {
          const rekviziti = {
                 naslov: 'Modal Title'
             }
             ModalWrapperComponent = plitko ().find('ModalTitle ');
          ocekivati ​​(ModalWrapperComponent.props (). djeca) .toEqual ('Modal Title');
      });

      Primanje ispravne prezentacije:

      it ('provjerite vrijednost prop', () => {
              const rekviziti = {
                     pokazati: istina
                 }
                 ModalWrapperComponent = plitko ().find('Modal ');
              očekivati ​​(ModalWrapperComponent.props () emisija.) .toEqual (istina);
          });

      Ispitivanje protipista

      • Za predstava
      it ('check type prop', () => {
          const rekviziti = {
                 pokazati: istina
              }
              ModalWrapperComponent = plitko ().find('Modal ');
          očekivati ​​(ModalWrapperComponent.props () emisija.) .toBeBoolean ();
      });
      • Za onHide prop
      it ('render to on on Hide type type', () => {
          const rekviziti = {
                  onHide: () => {}
              }
              ModalWrapperComponent = plitko ().find('Modal ');
          očekivati ​​(ModalWrapperComponent.props () onHide). .toBeFunction ();
      });
      • Za komponentu prop
      it ('uzmi ispravnu vrstu podupiranja komponente', () => {
         const rekviziti = {
                 komponenta: () => {}
             }
             ModalWrapperComponent = montirati ();
         očekuju (ModalWrapperComponent.props () komponenta.) .toBeFunction ();
      });

      Potpuni popis testova: ModalWrapper.test.js

      2.Code popis za testiranu komponentu: ModalTrigger.js

      Modalni omotač je prekriven testom. Drugi dio je pokrivanje modalne komponente okidača.

      Pregled komponente: zasnovan je na stanju koji pokazuje vidljivost ModalWrapper-a. Ako se prebaci: lažno, skočni prozor je skriven, inače je vidljiv. Funkcija open () otvara skočni prozor na podređenom elementu. Događaj klika i funkcija close () skriva skočni prozor na gumbu prikazanom u ModalWrapper.

      Izrada snimka:

      it ('ispravno prikaži komponentu ModalTrigger', () => {
          const ModalTriggerComponent = plitko ( 
      );     očekivati ​​(ModalTriggerComponent) .toMatchSnapshot (); });

      Trebamo li testirati ModalTrigger sa prikazom komponentnog potpornja? Ne - jer će se komponenta prikazati unutar komponente ModalWrapper. Ne ovisi o ispitivanoj komponenti. Već je bila prekrivena testovima u testovima ModalWrapper.

      Ispitivanje rekvizita:

      Imamo jedno dijete i želimo biti sigurni da imamo samo jedno dijete.

      it ('osigurati da ima samo jedno dijete (upravljački element)', () => {
          očekivati ​​(ModalTriggerComponent.findWhere (node ​​=> node.key () === 'modal-control'). dužina) .toEqual (1);
      });

      Proptipovi ispitivanja:

      Dječji podupirač trebao bi biti objekt, pa to provjerite u sljedećem testu:

      const ModalTriggerComponent = mount ( 
      );
      it ('provjeri vrstu propitivanja djece', () => {
            očekivati ​​(ModalTriggerComponent.props () djecu.) .toBeObject ();
      });

      Važan dio komponente ModalTrigger je provjera stanja.

      Imamo dvije države:

      • Otvara se skočni prozor. Da bismo znali da je modal otvoren, moramo provjeriti njegovo stanje. Za to nazovite otvorenu funkciju iz instancije komponente i očekujte da bi preklopljeni status trebao biti istinit.
      it ('provjeri da li je modal otvoren', () => {
          const događaj = {
              prevenDefault: () => {},
              stopPropagacija: () => {}
          };
          ModalTriggerComponent.instance () otvoren (događaj).
          očekivati ​​(ModalTriggerComponent.state () izmjenjivati). .toBeTruthy ();
      });
      • Popup je zatvoren. Testirano je obrnuto, preklapano stanje bi trebalo biti lažno.
      it ('provjerite je li modal zatvoren', () => {
         ModalTriggerComponent.instance () u neposrednoj blizini ().
         očekivati ​​(ModalTriggerComponent.state () izmjenjivati). .toBeFalsy ();
      });

      Potpuni popis testova: ModalTrigger.test.js

      Sada su modaliteti u potpunosti testirani. Savjet za testiranje komponenata koje ovise jedna o drugoj: prvo pregledajte komponente i napišite plan testa, definirajte što trebate testirati u svakoj komponenti, provjerite ispitne slučajeve za svaku komponentu i budite sigurni da ne ponovite isti testni slučaj u obje komponente. Pažljivo analizirajte moguće i optimalne varijante pokrivanja ispitivanja.

      5. Ispitivanje HOC-a (komponenta višeg reda)

      Zadnja dva dijela (testiranje HOC-a i polja obrasca) međusobno su povezana. Želio bih s vama podijeliti kako testirati izgled polja s njegovim HOC-om.

      Evo objašnjenja što je BaseFieldLayout, zašto nam je potrebna ova komponenta i gdje je koristimo:

      • BaseFieldLayout.js je omotač za komponente unosa oblika poput TextInput, CheckboxInput, DateInput, SelectInput itd. Njihova imena završavaju s -Input, jer koristimo paket reduks oblika, a te komponente su ulazne komponente za logiku redukcijskog oblika.
      • Potreban nam je BaseFieldLayout za izradu izgleda komponenata polja obrasca, odnosno isticanja naljepnica, savjeta, prefiksa (valuta, kratica kvadratnih metara itd.), Ikona, grešaka i tako dalje.
      • Koristimo ga u BaseFieldHOC.js za umotavanje inputComponenta u izgled polja i povezivanje s reduks-formom uz pomoć komponente.

      Popis kodova za testiranu komponentu: BaseFieldHOC.js

      To je HOC koji prima komponentu za unos obrasca i vraća komponentu, povezanu s redukcijskim oblikom.

      Analiza HOC-a:

      • Ova komponenta prima samo jednu pomoćnu komponentu. Prije svega, moram stvoriti ovu komponentu i zamotati je u BaseFieldHOC.
      • Zatim moram ukrasiti omotani HOC reduks-formom kako bih se polje povezalo sa reduks-formom.
      • Ispunite ovo polje unutar komponente React Redux kako bi trgovina bila dostupna testiranoj komponenti. Da biste se rugali trgovini, samo učinite:
      const store = createStore (() => ({}));

      Prije svakog testa, moram učiniti sljedeće:

      neka BaseFieldHOCComponent;
      beforeEach (() => {
          const TextInput = () => {return 'unos teksta'; }
              BaseFieldHOCWrapper = BaseFieldHOC (TextInput),
              TextField = reduxForm ({oblik: 'testForm'}) (BaseFieldHOCWrapper);
          BaseFieldHOCComponent = renderer.create (
              
                  
              
          ) .ToJSON ();
      });

      Nakon toga, komponenta je spremna za testiranje:

      1. Napravite snimku:
      it ('ispravno ispostavi komponentu', () => {
          očekivati ​​(BaseFieldHOCComponent) .toMatchSnapshot ();
      });

      2. Provjerite je li ulazna komponenta umotana u BaseFieldLayout nakon prikazivanja:

      it ('komponenta za provjeru je unesena u BaseFieldLayout', () => {
          očekivati ​​(BaseFieldHOCComponent.props.className) .toEqual ( "oblik-skupina);
      });

      To je sve, HOC je pokriven. Najsloženiji dio u ispitivanju komponenata povezanih sa reduks-formom je priprema polja (ukrasite reduksom i postava za pohranu). Ostalo je jednostavno, samo slijedite upute i ništa drugo.

      Potpuni popis testova: BaseFieldHOC.test.js

      6. Ispitivanje oblika / polja

      Polje HOC prekriveno je testovima pa se možemo prebaciti na komponentu BaseFieldLayout.

      Popis kodova za testiranu komponentu: BaseFieldLayout.js

      Kôdimo BaseFieldLayout.js i napišite testove prema uputama gore:

      1. Prije svega, stvorite snimku.

      Ova se komponenta neće prikazati bez defaultProps:

      • inputComponent
      • Podupirači koje pruža redukcijski oblik: ulaz i meta objekti. Unos s imenom svojstva i meta s greškom svojstva i dodirnite:
      const defaultProps = {
         meta: {
              dotaknuo: nula,
              pogreška: null
          }
          ulaz: {
              name: 'ime polja'
          }
          inputComponent: () => {return 'test case'; }
      }

      Da biste koristili defaultProps u svakom testiranom omotu, učinite sljedeće:

      uvesti TestBaseFieldLayout iz '../BaseFieldLayout';
      const BaseFieldLayout = (rekviziti) => ;

      Sad smo spremni za stvaranje snimka:

      it ('ispravno ispostavi komponentu BaseFieldLayout', () => {
          const BaseFieldLayoutComponent = renderer.create (). toJSON ();
          očekivati ​​(BaseFieldLayoutComponent) .toMatchSnapshot ();
      });

      2. Ispitivanje rekvizita:

      Ova komponenta ima mnogo rekvizita. Pokazat ću nekoliko primjera, a ostatak će biti testiran analogijom.

      • Provjerite je li podupirač ikona pravilno izveden
      it ('ispravno prikaži ikonu prop', () => {
          const rekviziti = {
                  ikona: 
              }
              BaseFieldLayoutComponent = montirati ();
              očekivati ​​(BaseFieldLayoutComponent.find ( 'vijek') hasClass ( 'ikona usklik').) toBeTruthy ().
      });
      • Osigurajte da se sadržaj pod porukom prikazuje pored oznake
      const rekviziti = {
              labelTooltipContent: 'opis za oznaku'
          }
          BaseFieldLayoutComponent = montirati ();
      it ('provjera je poduprta', () => {
         očekivati ​​(BaseFieldLayoutComponent.find ( 'vijek') hasClass ( 'tooltip-ikona').) toBeTruthy ().
      });
      • Polje za testiranje Link link
      • Uvjerite se da je polje FieldLink zadano u nuli
      it ('check prop je zadano nula', () => {
          const BaseFieldLayoutComponent = plitko ();
          očekivati ​​(BaseFieldLayoutComponent.props () fieldLink). .toBe (nula);
      });
      • Uvjerite se da fieldLink ispravno prikazuje prilagođenu vrijednost

      3. Pogreške ispitivanja:

      it ('provjeri ima li polje grešku', () => {
          const rekviziti = {
                  meta: {
                      dotaknuo: istina,
                      pogreška: 'ovo polje je obavezno'
                  }
              }
              BaseFieldLayoutComponent = montirati ();
          očekivati ​​(BaseFieldLayoutComponent.find () pogreška.) toHaveLength (1).
      });

      Potpuni popis testova: BaseFieldLayout.test.js

      Poanta

      Sada znate kako provesti testiranje komponenata na osnovi projektne strukture. Iz vlastitog iskustva pokušao sam objasniti što je potrebno testirati, kojim redoslijedom i što možete izostaviti u pokrivanju testa. Također sam demonstrirao primjere nekoliko komponenti za testiranje i uočio redoslijed pokrivanja baze podataka.

      Nadam se da će vam ovaj članak biti koristan i podijelit ćete svoje odgovore. Hvala na čitanju.

      Ako smatrate da je ovaj post koristan, dodirnite gumb below ispod :)