Komponentu pārbaude Reaktīvā: ko un kā testēt ar Jest un Enzyme.

Šo rakstu par reaģējošo komponentu testēšanu raksta Aļona Psarenko - Django Stars frontenžu inženiere.
Lasiet oriģinālo rakstu Django Stars emuārā.

React komponentu pārbaude var būt izaicinājums iesācējiem, kā arī pieredzējušiem izstrādātājiem, kuri jau ir strādājuši ar testiem. Var būt interesanti salīdzināt savas pieejas ar tām, kuras mēs izmantojam mūsu projektā. Lai aptvertu kodu bāzi, jums jāzina, kuras sastāvdaļas ir jāpārbauda un kurš tieši komponentā iekļautais kods ir jāaptver.

Šī raksta laikā es apskatīšu šādas tēmas:

  • Definējiet pareizu komponentu testēšanas secību, pamatojoties uz projekta struktūru
  • Atrodiet, ko izlaist testa pārklājumā (ko nepārbaudīt)
  • Nosakiet momentuzņēmumu pārbaudes nepieciešamību
  • Definējiet, ko testēt komponentā un kādā secībā
  • Sniedziet detalizētus pielāgotā koda piemērus

Rakstā ir prasīts, lai jums būtu zināšanas par Jest un Enzyme iestatīšanu. Informāciju par instalēšanu un konfigurēšanu var viegli atrast viņu oficiālajās vietnēs.

Pieņemsim, ka ir šāds gadījums: jums ir jāpārklāj projekta kopa ar testiem. Ar ko jums vajadzētu sākt, un kas jums vajadzētu iegūt pārbaudes beigās? 100% testa pārklājums? Tas ir etalons, uz kuru jums jācenšas sasniegt, taču vairumā gadījumu jūs to nesaņemsit.

Kāpēc? Tā kā jums nevajadzētu pārbaudīt visu kodu. Mēs uzzināsim, kāpēc un kas būtu jāatstāj ārpus pārbaudēm. Pat vairāk, 100% testa pārklājums ne vienmēr nodrošina komponentes pilnīgu pārbaudi. Nav arī garantijas, ka tas jums paziņos, ja kaut kas tiks mainīts. Nemēģiniet sasniegt procentus, nevairieties no viltus testu rakstīšanas un vienkārši mēģiniet nepazaudēt galveno detaļu detaļas.

Pareiza komponentu testēšanas secības noteikšana, pamatojoties uz projekta struktūru

Apspriedīsim šo jautājumu nākamajā projekta struktūras daļā:

Es paņēmu koplietojamo direktoriju, jo tas ir vissvarīgākais. Tas sastāv no komponentiem, kas tiek izmantoti vairākās dažādās projekta lappusēs. Tie ir atkārtoti lietojami, parasti tie ir mazi un nav sarežģīti. Ja viens vai otrs komponents neizdodas, tas citās vietās izraisīs kļūmi. Tāpēc mums vajadzētu būt pārliecinātiem, vai tie ir uzrakstīti pareizi. Šī direktorija struktūra ir sadalīta vairākās mapēs, no kurām katra satur komponentus.

Kā pareizi noteikt komponentu testēšanas secību koplietotajā direktorijā:

  • Vienmēr ievērojiet noteikumu par pāreju no vienkārša uz sarežģītu. Izanalizējiet katru direktoriju un definējiet, kuri komponenti ir neatkarīgi, proti, to atveidošana nav atkarīga no pārējiem komponentiem. Tie ir pašu aizpildīti, un tos var izmantot atsevišķi kā vienu vienību. No iepriekšējās struktūras tas ir ievades direktorijs veidlapu mapē. Tas satur ievades komponentus redux formās, piemēram, TextInput, SelectInput, CheckboxInput, DateInput utt.
  • Tālāk mums jādefinē palīgkomponenti, kurus bieži izmanto ieejas komponentos, bet tie jātestē atsevišķi. Šis ir utils direktorijs. Šīs mapes komponenti nav sarežģīti, bet ļoti svarīgi. Tie bieži ir atkārtoti lietojami un palīdz ar atkārtotām darbībām.
  • Nākamais solis ir noteikt, kurus komponentus var izmantot arī neatkarīgi. Paņemiet tos pārbaudei, ja tāds ir. No mūsu struktūras tie ir logrīki, mazie komponenti ar vienkāršu funkcionalitāti. Tie būs trešais postenis testa seguma rindā.
  • Tālāk analizējiet pārējos direktorijus un definējiet sarežģītākus komponentus, kurus var izmantot neatkarīgi vai kopā ar citiem komponentiem. Mūsu gadījumā tas ir modālo direktorijs. Šīs sastāvdaļas tiks detalizēti paskaidrotas zemāk.
  • Sarežģītākās sastāvdaļas tiek atstātas līdz beigām. Tie ir speciālais direktorijs un lauki no veidlapu mapes. Kā jūs definējat, kurš vispirms jāpārbauda? Es ņemu direktoriju, kurā komponenti jau ir izmantoti pārbaudītajos komponentos. Tādējādi logrīku komponentā atradās komponents no hoc direktorijas. Tāpēc es jau zinu, kur un kādam mērķim tiek izmantots šis direktorijs un tā sastāvdaļa.
  • Pēdējais ir lauku mape. Tas satur komponentus, kas saistīti ar redux formām.

Galīgais komponentu pasūtījums (pamatojoties uz mūsu piemēru) izskatīsies šādi:

Ievērojot šo pasūtījumu, jūs soli pa solim palielināt pārbaudīto komponentu sarežģītību. Tādējādi, strādājot ar sarežģītākiem komponentiem, jūs jau zināt, kā uzvedas paši mazākie.

Nelietojiet pārbaudi, piemēram, laukam “masīvs”, ja neesat pārliecināts, kā pārbaudīt “teksta” lauku. Nelietojiet komponentus, kas dekorēti ar reduktīvo formu, ja neesat pārbaudījis pašu veidlapas lauku.

Esiet konsekvents savās izvēlēs, neņemiet vērā pirmo komponentu, kas jums ienāk prātā, un mainiet loģiku. Protams, jūsu projekta struktūra var atšķirties. Tam var būt citi direktoriju nosaukumi vai arī tam var būt papildu komponenti, darbības un reduktori, taču komponentu testēšanas secības noteikšanas loģika ir vienāda.

Definēsim, kas testa izlaidumā būtu jāizlaiž:

  • Trešo pušu bibliotēkas. Nepārbaudi funkcionalitāti, kas tiek ņemta no citas bibliotēkas. Jūs neesat atbildīgs par šo kodu. Izlaidiet to vai atdariniet ieviešanu, ja tas ir nepieciešams koda pārbaudei.
  • Konstantes. Nosaukums pats par sevi runā. Tie nav maināmi. Tie ir statiskā koda komplekti, kuriem nav paredzēts mainīties.
  • Iekļautie stili (ja tos izmantojat savā komponentā). Lai pārbaudītu inline stilus, jums ir jākopē objekts ar testā esošajiem stiliem. Ja mainās objektu stili, tie jāmaina arī testā. Nepārkopējiet komponenta kodu testos. Jūs nekad neaizmirsīsit to mainīt testos. Turklāt jūsu kolēģis nekad nesapratīs, ka ir notikusi dublēšanās. Lielākajā daļā gadījumu iestrādātie stili nemaina komponenta izturēšanos, tāpēc tos nevajadzētu pārbaudīt. Var būt izņēmums, ja jūsu stili mainās dinamiski.
  • Lietas, kas nav saistītas ar pārbaudīto komponentu. Izlaist segumu ar testa komponentiem, kas tika importēti pārbaudītajā komponentā. Esiet piesardzīgs, ja tas ir iesaiņots citā. Nepārbaudiet iesaiņojumu, vienkārši analizējiet un pārbaudiet tos atsevišķi.

Tātad, kā jūs faktiski rakstāt testus? Es apvienoju divas testēšanas pieejas:

  • Momentuzņēmuma pārbaude
  • Komponentu loģikas pārbaude

Tagad apspriedīšu viņus abus.

Kā pārbaudīt ar momentuzņēmumiem

Momentuzņēmumu pārbaude ir noderīgs pārbaudes rīks, ja vēlaties pārliecināties, ka lietotāja interfeiss nav mainījies. Pirmoreiz saskaroties ar šo pārbaudes rīku, jums var rasties jautājumi par momentuzņēmumu organizēšanu un pārvaldību. Princips ir ļoti vienkāršs, bet diemžēl tas nekur nav pilnībā aprakstīts.

1. solis. Uzrakstiet komponenta pārbaudi un sagaidāmajā blokā izmantojiet metodi .toMatchSnapshot (), kas pati izveido momentuzņēmumu:

it ('pareizi atveidot teksta sastāvdaļu', () => {
    const TextInputComponent = renderētājs.create (). toJSON ();
    sagaidīt (TextInputComponent) .toMatchSnapshot ();
});

2. solis. Pirmoreiz palaižot testu vienā līmenī, vienlaikus ar testu, tiks izveidots direktorijs ar nosaukumu __snapshots__, kura iekšpusē automātiski ģenerēts fails ar paplašinājumu.snap.

Momentuzņēmums izskatās šādi:

// Jest Snapshot v1, https://goo.gl/fbAQLP
eksportē [`Render TextInput pareizi 1. komponentu`] =`

`;

3. solis. Ievietojiet momentuzņēmumu krātuvē un glabājiet to kopā ar testu.

Ja komponents ir mainīts, jums vienkārši jāatjaunina momentuzņēmums ar —updateSnapshot karodziņu vai jāizmanto saīsne u.

Tātad momentuzņēmums ir izveidots - kā tas darbojas?

Apsvērsim divus gadījumus:

1. Komponents ir mainīts

  • Palaist testus
  • Ir izveidots jauns momentuzņēmums, tas tiek salīdzināts ar automātiski ģenerētu momentuzņēmumu, kas glabājas direktorijā __snapshots__
  • Pārbaudes neizdevās, jo momentuzņēmums ir atšķirīgs

2. Komponents nav mainījies

  • Palaist testus
  • Ir izveidots jauns momentuzņēmums, tas tiek salīdzināts ar automātiski ģenerētu momentuzņēmumu, kas glabājas direktorijā __snapshots__
  • Pārbaudes izturētas, jo momentuzņēmums ir identisks

Viss ir kārtībā, ja pārbaudām nelielu komponentu bez loģikas (tikai UI atveidošana). Bet kā liecina prakse, reālos projektos šādu komponentu nav. Ja tādi pastāv, to ir maz.

Vai ir pietiekami daudz momentuzņēmumu pilnīgai komponentu pārbaudei?

Galvenie norādījumi par sastāvdaļu pārbaudi

1. Vienā komponentā jābūt tikai vienam momentuzņēmumam.

Ja viens momentuzņēmums neizdodas, visticamāk, neizdosies arī citi. Neveidojiet un neuzglabājiet virkni nevajadzīgu momentuzņēmumu, kas aizsērē vietu un mulsina izstrādātājus, kuri lasīs jūsu testus pēc jums.

Protams, ir izņēmumi, kad jātestē komponenta darbība divos stāvokļos: piemēram, komponenta stāvoklī pirms uznirstošā loga atvēršanas un pēc atvēršanas.

Tomēr pat šādu variantu vienmēr var aizstāt ar šo: pirmais tests saglabā komponenta noklusējuma stāvokli bez uznirstošā momentuzņēmuma, un otrais tests simulē notikumu un pārbauda noteiktas klases klātbūtni. Tādā veidā jūs varat viegli apiet vairāku momentuzņēmumu izveidi.

2. Butaforiju pārbaude

Parasti balstu pārbaudi es sadala divās pārbaudēs:

  • Pirmkārt, pārbaudiet noklusējuma rekvizītu vērtības. Kad komponents tiek renderēts, es sagaidu, ka vērtība būs vienāda ar defaultProps gadījumā, ja šim rekvizītam ir defaultProps.
  • Otrkārt, pārbaudiet rekvizīta pielāgoto vērtību. Es pats nosaku vērtību un gaidu, ka tā tiks saņemta pēc komponenta atveidošanas.

3. Datu veidu pārbaude

Lai pārbaudītu, kāda veida dati atrodas rekvizītos vai kāda veida dati tiek iegūti pēc noteiktām darbībām, mēs varam izmantot īpašo bibliotēku jest-pagarināts (Papildu Jest saskaņotāji), kurai ir paplašināts atbilstības komplekts, kuras nav Džest. Izmantojot šo bibliotēku, datu tipu pārbaude ir daudz vienkāršāka un patīkamāka.

Turpretī propiitu pārbaude ir pretrunīgs jautājums. Daži izstrādātāji var iebilst pret propītu veidu pārbaudi, jo tā ir trešās puses pakete, un to nevajadzētu pārbaudīt. Tomēr es uzstāju, ka jāpārbauda komponentu profili, jo pats nepārbaudu komplekta funkcionalitāti. Tā vietā es tikai pārliecinos, ka pareizais profils ir pareizs. Datu tips ir ļoti svarīga programmēšanas daļa, un to nevajadzētu izlaist.

4. Notikumu pārbaude

Pēc momentuzņēmuma izveidošanas un butaforijas pārklājuma ar testiem, jūs varat būt pārliecināti, ka komponents atveidosies pareizi. Bet ar to nepietiek, lai pilnībā pārklātu, ja komponentā ir notikumi.

Jūs varat pārbaudīt notikumu vairākos veidos. Visplašāk tiek izmantotas:

  • izspēles notikums => simulē to => sagaidāms, ka notikums tika izsaukts
  • izspēles notikums => simulē notikumu ar parametriem => sagaidāms, ka notikums tika izsaukts ar nodotajām parametriem
  • nokārtot nepieciešamos rekvizītus => padarīt komponentu => simulēt notikumu => sagaidīt noteiktu uzvedību izsauktajā notikumā

5. Pārbaudes apstākļi

Ļoti bieži jums var būt nosacījumi noteiktas klases izvadei, noteiktas koda sadaļas atveidošanai, vajadzīgo rekvizītu pārsūtīšanai utt. Neaizmirstiet par to, jo ar noklusējuma vērtībām pārbaudi izturēs tikai viena filiāle, bet otrā paliks nepārbaudīta.

Sarežģītos komponentos ar aprēķiniem un daudziem nosacījumiem jūs varat palaist garām dažas filiāles. Lai pārliecinātos, ka visas koda daļas ir pārbaudītas, izmantojiet testa pārklājuma rīku un vizuāli pārbaudiet, kuras filiāles ir pārklātas un kuras nav.

6. Pārbaudes stāvoklis

Lai pārbaudītu stāvokli, vairumā gadījumu ir jāraksta divi testi:

  • Pirmais pārbauda pašreizējo stāvokli.
  • Otrais pārbauda stāvokli pēc notikuma izsaukšanas. Izveidošanas komponents => zvana funkcija tieši testā => pārbaudiet, kā mainījies stāvoklis. Lai izsauktu komponenta funkciju, jums jāiegūst komponenta piemērs un tikai pēc tam jāizsauc tā metodes (piemērs ir parādīts nākamajā testā).

Pēc tam, kad būsit iepazinies ar šo instrukciju sarakstu, jūsu komponents tiks pārklāts no 90 līdz 100%. Es atstāju 10% īpašiem gadījumiem, kas nebija aprakstīti rakstā, bet var rasties kodā.

Pārbaudes piemēri

Pārcelsimies uz piemēriem un iekļausim testus komponentos, kā mēs soli pa solim aprakstījām iepriekš.

1. Komponenta pārbaude no formām / ievadiem.

Paņemiet vienu komponentu no veidlapu / ievades direktorijas. Lai tas būtu DateInput.js, datuma atlasītāja lauka komponents.

Pārbaudītā komponenta kodu saraksts: DateInput.js
Izskatās kā:

Komponents DateInput izmanto bibliotēkas reaģēšanas datuma atlasītāju ar divām utilītām:

  • valueToDate (konvertē vērtību uz datumu)
  • dateToValue (pārvērš datumu vērtībā)

Komplekts ir paredzēts manipulācijām ar datumu, un PropTypes ir paredzēts React rekvizītu pārbaudei.

Saskaņā ar komponenta kodu mēs varam redzēt noklusējuma rekvizītu sarakstu, kas palīdz komponentam iegūt:

const defaultProps = {
    inputClassName: 'input-custom',
    mēneši parādīts: 1,
    dateFormat: “DD.MM.GGGG”,
    showMonthYearsDropdowns: false,
    minDate: moments ()
};

Momentuzņēmuma izveidošanai ir piemēroti visi rekvizīti, izņemot vienu: minDate: moment (). moment () rādīs mums pašreizējo datumu katru reizi, kad mēs veiksim pārbaudi, un momentuzņēmums neizdosies, jo tajā tiek saglabāts novecojis datums. Risinājums ir ņirgāties par šo vērtību:

const defaultProps = {
    minDate: moments (0)
}

Katrā atveidotajā komponentā ir nepieciešams minDate rekvizīts. Lai izvairītos no rekvizītu dublēšanās, es izveidoju HOC, kas saņem defaultProps un atgriež diezgan labu komponentu:

importēt TestDateInput no '../DateInput';
const DateInput = (rekvizīti) =>
    ;

Neaizmirstiet par laika joslu, it īpaši, ja jūsu testus veiks izstrādātāji no citas valsts citā laika joslā. Viņi saņems izsmietās vērtības, bet ar laika joslas maiņu. Risinājums ir iestatīt noklusējuma laika joslu:

const moment = need.requireAtific ('moment-timezone'). tz.setDefault ('America / Los_Angeles')

Tagad datuma ievades komponents ir gatavs pārbaudei:

1. Vispirms izveidojiet momentuzņēmumu:

it ('pareizi renderēt datuma komponentu', () => {
    const DateInputComponent = render.create (). toJSON ();
    sagaidīt (DateInputComponent) .toMatchSnapshot ();
});

2.Izmēģinājuma rekvizīti:

Skatieties caur rekvizītiem un atrodiet svarīgos. Pirmais pārbaudāmais balsts ir showMonthYearsDropdowns. Ja tā ir patiesa, tiek parādīts nolaižamais mēnesis un gadi:

tas ('Pārbaudīt parādītos mēneša un gadu nolaižamos izvēlnes', () => {
    const rekvizīti = {
            showMonthYearsDropdowns: patiess
        },
        DateInputComponent = uzstādīšana ().find('.datepicker ');
    sagaidīt (DateInputComponent.hasClass ('react-datepicker-hide-month')) .Equal (true);
});

Pārbaudiet nulles vērtības vērtību. Šī pārbaude ir nepieciešama, lai pārliecinātos, ka komponents tiek renderēts bez noteiktas vērtības:

it ('pareizi renderēt datuma ievadi ar nulles vērtību', () => {
    const rekvizīti = {
            vērtība: nulle
        },
        DateInputComponent = uzstādīšana ();
    sagaidīt ((DateInputComponent) .prop ('vērtība')) .Equal (null);
});

3.Pārbaudes vērtības paraugi, datums, kurā paredzēts iegūt virkni:

it ('pārbaudiet vērtības veidu', () => {
    const rekvizīti = {
            vērtība: '0,103.2018 '
        },
        DateInputComponent = uzstādīšana ();
    sagaidīt (DateInputComponent.prop ('vērtība')) .toBeString ();
});

4.Testēšanas pasākumi:

Vispirms pārbaudiet onChange notikumu.

  • izspēlesMainīt atzvanīšanu
  • render datuma ievades komponentu
  • imitējiet izmaiņu notikumu ar jaunu mērķa vērtību
  • un visbeidzot pārbaudiet, vai onChange notikums ir izsaukts ar jaunu vērtību.
it ('pārbaudiet onChange atzvanīšanu', () => {
    const onChange = jest.fn (),
        rekvizīti = {
            vērtība: '20 .01.2018 ',
            onChange
        },
        DateInputComponent = uzstādīšana ().find('input ');
    DateInputComponent.simulate ('mainīt', {mērķis: {vērtība: moments ('2018-01-22')}});
    gaidīt (onChange) .toHaveBeenCalledWith ('22 .01.2018 ');
});

Pēc tam pārliecinieties, vai datuma atlasītāja uznirstošais logs tiek atvērts pēc noklikšķināšanas uz datuma ievadīšanas. Šim nolūkam atrodiet datuma ievadi => simulējiet klikšķa notikumu => un sagaidiet uznirstošo logu, kad ir .react-datepicker.

tas ('pārbaudiet, vai uznirstošais datumsPicker ir atvērts', () => {
    const DateComponent = uzstādīšana (),
        dateInput = DateComponent.find ("input [type = 'text']");
    dateInput.simulate ('klikšķis');
    sagaidīt (DateComponent.find ('. react-datepicker')) toHaveLength (1);
});

Pilns testu saraksts: DateInput.test.js

2. Lietderības pārbaude:

Pārbaudītās utilītas kodu saraksts: valueToDate.js

Šīs utilītas mērķis ir pārveidot vērtību datumā ar pielāgotu formātu.

Pirmkārt, analizēsim doto lietderību un definēsim galvenos testēšanas gadījumus:

  1. Atbilstoši šīs utilītas mērķim tas pārveido vērtību, tāpēc mums šī vērtība jāpārbauda:
  • Ja vērtība nav noteikta: mums jābūt pārliecinātiem, ka utilīta neatgriezīs izņēmumu (kļūda).
  • Gadījumā, ja vērtība ir noteikta: mums jāpārbauda, ​​vai utilīta atgriež datuma datumu.

2. Atgrieztajai vērtībai vajadzētu piederēt momentu klasei. Tāpēc tam vajadzētu būt mirkļa piemēram.

3. Otrais arguments ir dateFormat. Pirms testiem iestatiet to kā nemainīgu. Tieši tāpēc tas tiks izturēts katrā testā, un tā atgriešanas vērtība tiks parādīta atbilstoši datuma formātam. Vai datuma formātu vajadzētu pārbaudīt atsevišķi? Laikam nē. Šis arguments nav obligāts - ja mēs nenosakām datuma formātu, lietderība netiks pārtraukta, un tas vienkārši atgriezīsies datumu noklusējuma formātā. Tas ir īslaicīgs darbs, mums nevajadzētu pārbaudīt trešo personu bibliotēkas. Kā jau minēju iepriekš, mēs nedrīkstam aizmirst par brīža un laika joslu; tas ir ļoti svarīgs punkts, īpaši izstrādātājiem no dažādām laika zonām.

Kodīsim:

  1. Uzrakstiet pārbaudi pirmajam gadījumam. Kad mums nav vērtības, tā ir tukša.
const formāts = 'DD.MM.GGGG';
it ('render valueToDate utilīta ar tukšu vērtību', () => {
    const value = valueToDate ('', formāts);
    sagaidīt (vērtība) .toEqual (nulle);
});

2. Pārbaudiet, vai vērtība ir noteikta.

const date = '21 .11.2015. ',
      formāts = “DD.MM.GGGG”;
it ('render valueToDate utilīta ar noteiktu vērtību', () => {
    const value = valueToDate (datums, formāts);
    sagaidīt (vērtība) .toEqual (brīdis (datums, formāts));
});

3. Pārbaudiet, vai vērtība pieder pie momenta klases.

const date = '21 .11.2015. ',
    formāts = “DD.MM.GGGG”;
it ('pārbaudes vērtība ir momenta piemērs', () => {
    const value = valueToDate (datums, formāts);
    sagaidīt (momenta vērtības piemērs) .toBeTruthy ();
});

Pilns testu saraksts: valueToDate.test.js

3. Logrīku pārbaude

Logrīku pārbaudei es paņēmu vērpšanas komponentu.

Kodu saraksts pārbaudītajam logrīkam: Spinner.js

Izskatās šādi:

Skaidrojums nav nepieciešams skaidrojumā, jo gandrīz visiem tīmekļa resursiem ir šī sastāvdaļa.

Tātad, ja mēs ejam rakstīt testus:

  1. Pirmais solis - momentuzņēmuma izveidošana:
it ('pareizi renderēt Spinner komponentu', () => {
   const SpinnerComponent = stiprinājums ();
   sagaidīt (SpinnerComponent) .toMatchSnapshot ();
});

2. Butaforijas pārbaude:

Vispirms mēs aplūkojam noklusējuma rekvizīta nosaukumu un pārbaudām, vai tas tiek pareizi parādīts.

it ('pēc noklusējuma pārbaudīt rekvizīta titulu', () => {
 const SpinnerComponent = stiprinājums ();
    gaidīt (SpinnerComponent.find ('p'). teksts ()). toEqual ('Lūdzu uzgaidiet');
});

Tad mēs pārbaudām pielāgotā rekvizīta nosaukumu. Mums jāpārbauda, ​​vai tas atgriež pareizi definētu rekvizītu. Apskatiet kodu, nosaukums ir iesaiņots rawMarkup util un izvades ar īpašību bīstamiSetInnerHTML palīdzību.

Kodu saraksts rawMarkup util:

eksportēt noklusējuma funkciju rawMarkup (veidne) {
    atgriezt {__html: veidne};
}

Vai vārpstas komponentā jāiekļauj rawMarkup testi? Nē, tā ir atsevišķa lietderība, un tā jāpārbauda neatkarīgi no vērpšanas ierīces. Mums nav vienalga, kā tas darbojas - mums vienkārši jāzina, ka titulētais rekvizīts nodrošina pareizu rezultātu.

Skaidrojums: Īpašības bīstamiSetInnerHTML izmantošanas iemesls ir šāds. Mūsu vietne ir daudzvalodu, par kuru ir atbildīga tulkojumu mārketinga komanda. Viņi to var tulkot vienkārši ar vārdu salikumu vai pat izrotāt ar HTML tagiem, piemēram, , , vai pat sagriezt tekstu sarakstos

    ,
      . Mēs precīzi nezinām, kā viņi tulko un rotā tekstu. Mums tas viss ir pareizi jāveido.

      Es vienā testā apvienoju divus galvenos pārbaudes gadījumus:

      • atgriezt pareizo pielāgotā rekvizīta nosaukumu
      • pareizi noformējiet rekvizīta nosaukumu ar HTML tagiem
      it ('pārbaudiet rekvizīta virsrakstu ar html tagiem ", () => {
          const rekvizīti = {
                  nosaukums: ' Lūdzu, uzgaidiet '
              },
              SpinnerComponent = stiprinājums ();
          gaidīt (SpinnerComponent.find ('p'). teksts ()). toEqual ('Lūdzu uzgaidiet');
      });

      Paņemiet nākamo reklamēšanas apakšsadaļu. Tas nav obligāti, un tāpēc tam nav noklusējuma rekvizītu, tāpēc izlaidiet soli ar noklusējuma rekvizītiem un pārbaudiet pielāgotos rekvizītus:

      • Pārbaudiet, vai teksts apakšvirsraksta rekvizītos tiek pareizi parādīts:
      const rekvizīti = {
              apakšvirsraksts: 'atlicis 1 minūti'
          },
          SpinnerComponent = stiprinājums ();
      it ('render pareizu tekstu', () => {
          gaidīt (SpinnerComponent.find ('p'). pie (1) .text ()) .Equal (props.subTitle);
      });

      Mēs zinām, ka apakšvirsraksts nav obligāts. Tāpēc mums ir jāpārbauda, ​​vai tas netiek atveidots ar noklusējuma rekvizītiem saskaņā ar sagriešanas marķējumu. Vienkārši pārbaudiet tagu skaitu

      :

      tas ('pārbaudiet, vai apakšvirsraksts nav atveidots', () => {
        const SpinnerComponent = stiprinājums ();
          sagaidīt (SpinnerComponent.find ('p'). garums) .toEqual (1);
      });

      3.Izmēģinājumu tipu pārbaude:

      • Paredzamā virknes rekvizīta virknei
      it ('pārbaudiet rekvizīta veidu, vai nosaukumam ir virkne', () => {
          const rekvizīti = {
                  nosaukums: 'Pagaidiet'
              },
              SpinnerComponent = stiprinājums ();
          gaidīt (SpinnerComponent.find ('p'). teksts ()). toBeString ();
      });
      • Paredzams, ka apakšvirsraksta rekvizīts būs virkne:
      const rekvizīti = {
              apakšvirsraksts: 'atlicis 1 minūti'
          },
          SpinnerComponent = stiprinājums ();
      it ('subtitru tips ir virkne', () => {
          gaidīt (SpinnerComponent.find ('p'). pie (1) .text ()). toBeString ();
      });

      Pilns testu saraksts: Spinner.test.js

      4. Modālu pārbaude (ModalWrapper.js un ModalTrigger.js)

      Izskatās kā:

      Kā pārbaudīt modeļus

      Pirmkārt, es vēlos izskaidrot, kā mūsu projektā tiek organizēti modāli. Mums ir divas sastāvdaļas: ModalWrapper.js un ModalTrigger.js.

      ModalWrapper ir atbildīgs par uznirstošo izkārtojumu. Tajā ir modālais konteiners, poga “aizvērt”, modālā virsraksts un korpuss.

      ModalTrigger ir atbildīgs par modālu apstrādi. Tas ietver ModalWrapper izkārtojumu un satur pasākumus modāla izkārtojuma kontrolei (atvērtas un aizvērtas darbības).

      Es apskatīšu katru komponentu atsevišķi:

      1. Pārbaudītās sastāvdaļas kodu saraksts: ModalWrapper.js

      Kodīsim:

      Pirmkārt, ModalWrapper saņem komponentu un padara to iekšā. Vispirms pārbaudiet, vai ModalWrapper neizdosies bez komponenta. Izveidojiet momentuzņēmumu ar noklusējuma rekvizītiem:

      tas ('bez komponenta', () => {
          const ModalWrapperComponent = sekla ();
          sagaidīt (ModalWrapperComponent) .toMatchSnapshot ();
      });

      Nākamais solis ir simulēt tā faktisko stāvokli ar komponentu atveidošanu, kas iziet caur rekvizītiem:

      tas ('ar komponentu', () => {
         const rekvizīti = {
                 komponents: () => {}
              },
              ModalWrapperComponent = sekla ();
          sagaidīt (ModalWrapperComponent) .toMatchSnapshot ();
      });

      Butaforiju pārbaude

      Pielāgota klases nosaukuma saņemšana:

      it ('render pareizs klases nosaukums', () => {
          const rekvizīti = {
                  modalClassName: 'custom-class-name'
              },
              ModalWrapperComponent = sekla ().find('Modal ');
              sagaidīt (ModalWrapperComponent.hasClass ('pasūtījuma klases nosaukums')) .toEqual (true);
      });

      Pielāgota nosaukuma rekvizīta saņemšana:

      it ('render pareizs nosaukums', () => {
          const rekvizīti = {
                 nosaukums: “modālais nosaukums”
             },
             ModalWrapperComponent = sekla ().find('ModalTitle ');
          sagaidīt (ModalWrapperComponent.props (). bērni) .toEqual ('Modal Title');
      });

      Pareiza šova saņemšana:

      it ('pārbaudīt rekvizīta vērtību', () => {
              const rekvizīti = {
                     izrāde: taisnība
                 },
                 ModalWrapperComponent = sekla ().find('Modal ');
              sagaidīt (ModalWrapperComponent.props (). parādīt) .toEqual (true);
          });

      Proptu tipu pārbaude

      • Par šova prop
      tas ('pārbaudīt rekvizīta veidu', () => {
          const rekvizīti = {
                 izrāde: taisnība
              },
              ModalWrapperComponent = sekla ().find('Modal ');
          gaidīt (ModalWrapperComponent.props (). parādīt) .toBeBoolean ();
      });
      • Par onHide prop
      it ('renderēt onHide prop type', () => {
          const rekvizīti = {
                  onHide: () => {}
              },
              ModalWrapperComponent = sekla ().find('Modal ');
          gaidīt (ModalWrapperComponent.props (). onHide) .toBeFunction ();
      });
      • Komponentu prop
      it ('render pareizs komponenta rekvizīta tips', () => {
         const rekvizīti = {
                 komponents: () => {}
             },
             ModalWrapperComponent = mount ();
         sagaidīt (ModalWrapperComponent.props (). sastāvdaļa) .toBeFunction ();
      });

      Pilns testu saraksts: ModalWrapper.test.js

      2. Pārbaudītās sastāvdaļas kodu saraksts: ModalTrigger.js

      Modālais iesaiņojums ir pārklāts ar testu. Otrajā daļā paredzēts segt modālā sprūda komponentu.

      Komponentu pārskats: tas ir balstīts uz pārslēgtu stāvokli, kas norāda ModalWrapper redzamību. Ja pārslēgts: nepatiess, uznirstošais logs ir paslēpts, citur tas ir redzams. Funkcija open () atver uznirstošo elementu pakārtotajam elementam. Klikšķa notikums un funkcija close () paslēpj uznirstošo pogu uz ModalWrapper atveidotās pogas.

      Momentuzņēmuma izveidošana:

      it ('pareizi atveidot ModalTrigger komponentu', () => {
          const ModalTriggerComponent = sekla ( 
      );     sagaidīt (ModalTriggerComponent) .toMatchSnapshot (); });

      Vai mums būtu jāpārbauda ModalTrigger ar sastāvdaļu balsta atveidošanu? Nē - jo komponents tiks atveidots ModalWrapper komponentā. Tas nav atkarīgs no pārbaudītās sastāvdaļas. Tas jau bija pārklāts ar testiem ModalWrapper testos.

      Butaforijas pārbaude:

      Mums ir viens bērniņš bērniem, un mēs vēlamies būt pārliecināti, ka mums ir tikai viens bērns.

      it ('pārliecinieties, ka jums ir tikai viens bērns (vadības elements)', () => {
          sagaidīt (ModalTriggerComponent.findWhere (node ​​=> node.key () === 'modal-control'). length) .toEqual (1);
      });

      Pārbaudes ar propātiem:

      Bērnu balstam jābūt objektam, tāpēc pārbaudiet to nākamajā pārbaudē:

      const ModalTriggerComponent = stiprinājums ( 
      );
      tas ('pārbaudiet bērnu balstu veidu', () => {
            sagaidīt (ModalTriggerComponent.props (). bērni) .toBeObject ();
      });

      Svarīga ModalTrigger komponenta daļa ir stāvokļu pārbaude.

      Mums ir divi stāvokļi:

      • Tiek atvērts uznirstošais logs. Lai zinātu, ka modulis ir atvērts, mums jāpārbauda tā stāvoklis. Šim nolūkam no komponenta gadījuma izsauciet atvērto funkciju un gaidiet, ka ieslēgtajam stāvoklim jābūt patiesam.
      it ('pārbaudiet, vai modulis ir atvērts', () => {
          const notikums = {
              preventDefault: () => {},
              stopPropagation: () => {}
          };
          ModalTriggerComponent.instance (). Atvērts (pasākums);
          sagaidīt (ModalTriggerComponent.state (). pārslēgts) .toBeTruthy ();
      });
      • Uznirstošais logs ir aizvērts. Tas tiek pārbaudīts otrādi, pārslēgtā stāvoklī jābūt kļūdainam.
      it ('pārbaudiet, vai modulis ir aizvērts', () => {
         ModalTriggerComponent.instance (). Aizvērt ();
         sagaidīt (ModalTriggerComponent.state (). pārslēgts) .toBeFalsy ();
      });

      Pilns testu saraksts: ModalTrigger.test.js

      Tagad modāli ir pilnībā pārbaudīti. Viens padoms, lai pārbaudītu komponentus, kuri ir atkarīgi viens no otra: vispirms izpētiet komponentus un uzrakstiet testa plānu, definējiet, kas jāpārbauda katrā komponentā, pārbaudiet katras sastāvdaļas testa gadījumus un pārliecinieties, ka jums nav atkārtojiet to pašu testa gadījumu abās sastāvdaļās. Rūpīgi analizējiet iespējamos un optimālos testa pārklājuma variantus.

      5. HOC pārbaude (augstākas pakāpes komponents)

      Pēdējās divas daļas (HOC un formas lauku pārbaude) ir savstarpēji savienotas. Es vēlētos dalīties ar jums, kā pārbaudīt lauka izkārtojumu ar tā HOC.

      Tālāk ir paskaidrots, kas ir BaseFieldLayout, kāpēc mums ir nepieciešams šis komponents un kur mēs to izmantojam:

      • BaseFieldLayout.js ir iesaiņojums tādiem veidlapu ievades komponentiem kā TextInput, CheckboxInput, DateInput, SelectInput utt. To nosaukumi beidzas ar -Input, jo mēs izmantojam redux-form paketi, un šie komponenti ir ievades komponenti redux-formas loģikai.
      • Mums ir nepieciešams BaseFieldLayout, lai izveidotu veidlapu lauku komponentu izkārtojumu, ti, etiķetes, rīka padomu, prefiksu (valūta, kvadrātmetru saīsinājumi utt.), Ikonas, kļūdas utt.
      • Mēs to izmantojam BaseFieldHOC.js, lai iesaiņotu inputComponent lauka izkārtojumā un savienotu to ar redux formu ar komponenta palīdzību.

      Pārbaudītā komponenta kodu saraksts: BaseFieldHOC.js

      Tas ir HOC, kurš saņem formas ievades komponentu un atdod komponentu, kas savienots ar redux-formu.

      HOC analīze:

      • Šis komponents saņem tikai vienu balstu, komponentu. Pirmkārt, man ir jāizveido šis komponents un jāiesaiņo BaseFieldHOC.
      • Pēc tam man jāapzīmē iesaiņotais HOC ar redux formu, lai lauks būtu savienots ar redux formu.
      • Atkārtojiet šo lauku React Redux komponentā, lai veikals būtu pieejams pārbaudītajam komponentam. Lai ņirgātos par veikalu, vienkārši rīkojies šādi:
      const veikals = createStore (() => ({}));

      Tagad pirms katra testa man jādara šādi:

      ļaujiet BaseFieldHOCComponent;
      beforeEach (() => {
          const TextInput = () => {atgriezt 'teksta ievade'; },
              BaseFieldHOCWrapper = BaseFieldHOC (TextInput),
              TextField = reduxForm ({forma: 'testForm'}) (BaseFieldHOCWrapper);
          BaseFieldHOCComponent = render.create (
              
                  
              
          ) .toJSON ();
      });

      Pēc tam komponents ir gatavs pārbaudei:

      1. Izveidot momentuzņēmumu:
      it ('pareizi renderēt komponentu', () => {
          sagaidīt (BaseFieldHOCComponent) .toMatchSnapshot ();
      });

      2. Pārliecinieties, ka ievades elements ir iesaiņots BaseFieldLayout pēc renderēšanas:

      tas ('pārbaudiet, vai ievades komponents ir iesaiņots BaseFieldLayout', () => {
          sagaidīt (BaseFieldHOCComponent.props.className) .toEqual ('form-group');
      });

      Tas ir viss, uz HOC attiecas. Sarežģītākā sastāvdaļa, kas saistīta ar redux-formām, tiek pārbaudīta, sagatavojot lauku (rotājiet ar redux formu un iestatījumu veikalu). Pārējais ir viegli, vienkārši izpildiet instrukcijas un neko citu.

      Pilns testu saraksts: BaseFieldHOC.test.js

      6. Veidlapu / lauku pārbaude

      Lauks HOC ir pārklāts ar testiem, lai mēs varētu pāriet uz BaseFieldLayout komponentu.

      Pārbaudītā komponenta kodu saraksts: BaseFieldLayout.js

      Kodēsim BaseFieldLayout.js un uzrakstīsim testus saskaņā ar iepriekš sniegtajiem norādījumiem:

      1. Pirmkārt, izveidojiet momentuzņēmumu.

      Šis komponents netiks atveidots bez defaultProps:

      • inputComponent
      • Balsti, ko nodrošina redux-forma: ievades un meta objekti. Ievade ar īpašuma nosaukumu un meta ar kļūdu un pieskārienu:
      const defaultProps = {
         meta: {
              pieskāries: nulle,
              kļūda: nulle
          },
          ievade: {
              nosaukums: 'lauka nosaukums'
          },
          inputComponent: () => {atgriezt 'testa gadījumu'; }
      }

      Lai katrā pārbaudītajā iesaiņojumā izmantotu defaultProps, rīkojieties šādi:

      importēt TestBaseFieldLayout no '../BaseFieldLayout';
      const BaseFieldLayout = (butaforijas) => ;

      Tagad mēs esam gatavi izveidot momentuzņēmumu:

      it ('pareizi atveido BaseFieldLayout komponentu', () => {
          const BaseFieldLayoutComponent = render.create () .JJ ();
          sagaidīt (BaseFieldLayoutComponent) .toMatchSnapshot ();
      });

      2. Butaforijas pārbaude:

      Šim komponentam ir daudz butaforiju. Es parādīšu vairāku piemērus, un pārējos pārbaudīsim pēc analoģijas.

      • Pārliecinieties, vai ikonas rekvizīts tiek parādīts pareizi
      it ('render icon icon prop', () => {
          const rekvizīti = {
                  ikona: 
              },
              BaseFieldLayoutComponent = uzstādīšana ();
              sagaidīt (BaseFieldLayoutComponent.find ('span'). hasClass ('icon-exclamation')). ​​toBeTruthy ();
      });
      • Pārliecinieties, ka rīka padoma saturs tiek parādīts blakus etiķetei
      const rekvizīti = {
              labelTooltipContent: “etiķetes rīka padoms”
          },
          BaseFieldLayoutComponent = uzstādīšana ();
      it ('pārbaude tiek atveidota', () => {
         sagaidīt (BaseFieldLayoutComponent.find ('span'). hasClass ('tooltip-icon')). ​​toBeTruthy ();
      });
      • Pārbaude fieldLink prop
      • Pārliecinieties, ka fieldLink pēc noklusējuma nav spēkā
      tas ('pēc noklusējuma pārbaudiet, vai statīvs ir nulle', () => {
          const BaseFieldLayoutComponent = sekla ();
          sagaidīt (BaseFieldLayoutComponent.props (). fieldLink) .toBe (null);
      });
      • Pārliecinieties, vai fieldLink tiek pareizi attēlots ar pielāgoto vērtību

      3. Pārbaudes kļūdas:

      tas ('pārbaudiet, vai laukā nav kļūdas', () => {
          const rekvizīti = {
                  meta: {
                      pieskāries: patiess,
                      kļūda: 'Šis lauks ir obligāts'
                  }
              },
              BaseFieldLayoutComponent = uzstādīšana ();
          sagaidīt (BaseFieldLayoutComponent.find ('. kļūda')). toHaveLength (1);
      });

      Pilns testu saraksts: BaseFieldLayout.test.js

      Grunts līnija

      Tagad jūs zināt, kā veikt pilnīgu komponentu pārklājuma pārbaudi, pamatojoties uz projekta struktūru. Pēc savas pieredzes es centos izskaidrot, kas ir jāpārbauda, ​​kādā secībā un ko jūs varat izlaist testa aptverē. Es arī parādīju vairāku testēšanas komponentu piemērus un pamanīju kodu bāzes pārklājuma secību.

      Es ceru, ka šis raksts jums noderēs un dalīsies savās atbildēs. Paldies par lasīšanu.

      Ja jums šķiet, ka šī ziņa ir noderīga, lūdzu, pieskarieties pogai zemāk :)