Komponensek tesztelése a Reactban: mit és hogyan kell tesztelni a Jest és az Enzyme segítségével.

A reaktív alkatrészek teszteléséről szóló cikket Alona Pysarenko - a Django Stars frontend mérnöke írta.
Olvassa el az eredeti cikket a Django Stars blogján.

A React komponensek tesztelése kihívást jelenthet mind kezdők, mind tapasztalt fejlesztők számára, akik már dolgoztak a tesztekkel. Érdekes lehet összehasonlítani saját megközelítéseit azokkal, amelyeket a projektünkben használunk. A kódbázis lefedése érdekében tudnia kell, mely alkatrészeket kell tesztelni, és hogy melyik kódot kell pontosan lefedni.

A cikk során a következő témákat tárgyalom:

  • Határozza meg a komponensek tesztelésének helyes sorrendjét a projekt felépítése alapján
  • Keresse meg, mit hagyjon ki a teszt lefedettségében (mit ne teszteljen)
  • Azonosítsa a pillanatfelvétel tesztelésének szükségességét
  • Adja meg, hogy mit kell tesztelni az összetevőben és milyen sorrendben
  • Adjon meg részletes egyedi példaképeket

A cikk megköveteli, hogy rendelkezzen ismeretekkel a Jest és az Enzyme beállításaival kapcsolatban. A telepítéssel és a konfigurálással kapcsolatos információk könnyen megtalálhatók hivatalos webhelyeiken.

Tegyük fel a következő esetet: Be kell fednie a projekt kódját a tesztekkel. Mivel kell kezdenie, és mit kell kapnia a tesztelés végén? 100% -os teszt lefedettség? Ez a referenciaérték, amelyre törekednünk kell, de a legtöbb esetben nem kapja meg.

Miért? Mert nem szabad minden kódot kipróbálnia. Megtudjuk, hogy miért és mit kellene kihagyni a tesztekből. Sőt, a 100% -os teszt lefedettség nem mindig biztosítja az alkatrész teljes tesztelését. Az sem garantált, hogy értesíti Önt, ha valami megváltozott. Ne törekedjen a százalékos arányra, kerülje a hamis tesztek írását, és csak próbáljon meg ne veszíteni a fő alkatrész részleteit.

Az alkatrészek tesztelésének helyes sorrendjének meghatározása a projekt szerkezete alapján

Beszéljük meg ezt a kérdést a projekt felépítésének következő részében:

A megosztott könyvtárat vettem, mert ez a legfontosabb. Az összetevőkből áll, amelyeket a projekt több különböző oldalán használnak. Újrahasznosíthatóak, általában kicsik és nem bonyolultak. Ha egy vagy másik alkatrész meghibásodik, akkor másutt is meghibásodást okoz. Ezért kell bíznunk abban, hogy helyesen írták-e őket. A könyvtár felépítése több mappára van felosztva, amelyek mindegyike összetevőket tartalmaz.

Az összetevők tesztelésének helyes sorrendjének meghatározása a megosztott könyvtárban:

  • Mindig kövesse a szabályt, hogy az egyszerűtől a komplexig kerüljön. Elemezze az egyes könyvtárakat, és határozza meg, mely összetevők függetlenek - nevezetesen, hogy megjelenítésük nem függ a többi összetevőtől. Ezek önelkészültek, és külön-külön is felhasználhatók egyetlen egységként. A fenti struktúrától függően ez az űrlapok mappa bemeneti könyvtára. A redux-formák bemeneti elemeit tartalmazza, például a TextInput, SelectInput, CheckboxInput, DateInput stb.
  • Ezután meg kell határoznunk azokat a segédkomponenseket, amelyeket gyakran használunk a bemeneti komponensekben, de ezeket külön kell vizsgálni. Ez az utils könyvtár. A mappában szereplő összetevők nem bonyolultak, de nagyon fontosak. Gyakran újrahasznosíthatóak, és segítenek az ismételt műveletekben.
  • A következő lépés annak meghatározása, hogy mely komponenseket is lehet önállóan felhasználni. Ha van, vigye őket tesztelésre. Szerkezetünkből ez a kütyü, az egyszerű funkcionalitású kis alkatrészek. Ezek lesznek a harmadik tétel a teszt lefedettségi sorában.
  • Ezután elemezze a többi könyvtárat, és határozza meg a bonyolultabb összetevőket, amelyeket külön-külön vagy más összetevőkkel együtt lehet használni. A mi esetünkben a modális könyvtár. Ezeket az alkotóelemeket az alábbiakban részletesebben ismertetjük.
  • A legösszetettebb alkotóelemeket a végére hagyják. Ezek az eseti könyvtár és a mezők az űrlapok mappájában. Hogyan határozza meg, melyiket kell először tesztelni? A könyvtárat veszem, amelyből az összetevőket már használták a tesztelt összetevőkben. Így a hoc könyvtárból származó összetevő jelen volt a widget komponensben. Ezért már tudom, hogy hol és milyen célra használják ezt a könyvtárat és annak alkotórészét.
  • Az utolsó a mezők mappája. Redukciós alakokkal összekapcsolt komponenseket tartalmaz.

Az összetevők végső sorrendje (példánk alapján) így néz ki:

Ezt a sorrendet követve lépésről lépésre növeli a tesztelt alkatrészek összetettségét. Így amikor a bonyolultabb alkatrészekkel kell üzemeltetni, akkor már tudja, hogyan viselkednek a legkisebbek.

Ne vegye igénybe például a 'tömb' mező tesztelését, ha nem biztos benne, hogyan kell a 'szöveg' mezőt tesztelni. Ne vegye át a redux-formával díszített alkatrészeket, ha még nem tesztelte magát a „forma” mezőt.

Légy következetes a döntéseiben, ne vegye be az első olyan eszközt, amely eszébe jut, és váltson át a logikára. Természetesen a projekt felépítése eltérhet. Lehet, hogy más könyvtárneveket is tartalmazhat, vagy lehet további összetevőket, műveleteket és reduktorokat, de az összetevők tesztelési sorrendjének meghatározásának logikája ugyanaz.

Definiáljuk, mit kell kihagyni a teszt lefedettségében:

  • Külső könyvtárak. Ne tesztelje a másik könyvtárból származó funkciókat. Ön nem felelős azért a kódért. Hagyja ki, vagy utánozza a megvalósítást, ha szüksége van rá a kód teszteléséhez.
  • Állandók. A név önmagáért beszél. Nem változtathatók. Statikus kódkészletek, amelyek nem változtatnak.
  • Beépített stílusok (ha ezeket használja a komponensben). Az inline stílusok teszteléséhez meg kell másolni az objektumot a teszt stílusaival. Ha az objektumstílusok megváltoznak, akkor azokat meg kell változtatni a tesztben is. Ne lemásolja az összetevő kódját a tesztek során. Soha nem fogja szem előtt tartani, hogy megváltoztassa a tesztek során. Sőt, kollégája soha nem fogja észrevenni, hogy párhuzamos volt. A legtöbb esetben az inline stílusok nem változtatják meg az alkatrész viselkedését, ezért azokat nem szabad tesztelni. Kivétel lehet, ha stílusa dinamikusan megváltozik.
  • A tesztelt alkotóelemhez nem kapcsolódó dolgok. Átugrani a lefedést a tesztelt összetevőkkel, amelyeket a tesztelt összetevőbe importáltak. Vigyázzon, ha egy másikba van csomagolva. Ne tesztelje a csomagolást, csak elemezze és tesztelje külön.

Szóval hogyan írsz valójában teszteket? Két tesztelési megközelítést kombinálom:

  • Pillanatfelvétel tesztelése
  • Alkatrész logikai tesztelés

Most mindkettőt megvitatom.

Hogyan kell tesztelni pillanatképekkel

A pillanatfelvétel tesztelése hasznos tesztelő eszköz abban az esetben, ha biztos akar lenni abban, hogy a felhasználói felület nem változott meg. Amikor először szembesül ezzel a tesztelő eszközzel, kérdései merülhetnek fel a pillanatképek szervezésével és kezelésével kapcsolatban. Az elv nagyon egyszerű, de sajnos még senki nem írta le teljesen.

1. lépés: Írja le az összetevő tesztjét, és a várható blokkban használja a .toMatchSnapshot () metódust, amely maga hozza létre a pillanatfelvételt:

it ('helyesen renderelje meg a szöveges összetevőt', () => {
    const TextInputComponent = renderer.create (). toJSON ();
    számíthat (TextInputComponent) .toMatchSnapshot ();
});

2. lépés: A teszt első szintű futtatásakor egy szinten, a teszttel együtt, létrejön egy __snapshots__ nevű könyvtár, az automatikusan létrehozott fájllal a kiterjesztés.snap segítségével.

A pillanatkép így néz ki:

// Jest Snapshot v1, https://goo.gl/fbAQLP
exportálja a `` Render TextInput helyesen 1. komponenst '] = `

`;

3. lépés: Helyezze a pillanatfelvételt a lerakatba, és tárolja a teszttel együtt.

Ha az összetevő megváltozott, akkor csak frissítenie kell a pillanatfelvételt az —updateSnapshot zászlóval, vagy használnia kell az u űrlapot.

Így létrejön a pillanatkép - hogyan működik?

Vizsgáljuk meg két esetet:

1. Az alkatrész megváltozott

  • Futtasson teszteket
  • Létrejön egy új pillanatkép, összehasonlítva az automatikus generált pillanatképgel, amelyet a __snapshots__ könyvtárban tárolunk.
  • A tesztek sikertelenek voltak, mert a pillanatkép más

2. Az alkatrész nem változott

  • Futtasson teszteket
  • Létrejön egy új pillanatkép, összehasonlítva az automatikus generált pillanatképgel, amelyet a __snapshots__ könyvtárban tárolunk.
  • A tesztek sikeresek voltak, mert a pillanatkép azonos

Minden rendben, ha kicsi komponenst tesztelünk logika nélkül (csak felhasználói felület renderelés). De amint a gyakorlat azt mutatja, a valós projektekben nincsenek ilyen elemek. Ha léteznek, akkor kevés.

Van elegendő pillanatfelvétel a teljes alkatrész teszteléséhez?

Az alkatrészek tesztelésének fő útmutatásai

1. Az egyik összetevőnek csak egy pillanatképével kell rendelkeznie.

Ha az egyik pillanatkép sikertelen, akkor valószínűleg a többi is meghiúsul. Ne készítsen és tároljon egy csomó felesleges pillanatfelvételt, amely eltömíti a teret és zavarja a fejlesztőket, akik elolvassa a teszteket.

Természetesen vannak olyan kivételek, amikor egy elem viselkedését két állapotban kell tesztelnie: például az összetevő állapotában az előugró ablak megnyitása előtt és a megnyitás után.

Ugyanakkor még egy ilyen változat is helyettesíthető ezzel: az első teszt pillanatfelvétel nélkül tárolja az összetevő alapértelmezett állapotát, a második teszt pedig az eseményt szimulálja és ellenőrzi egy adott osztály jelenlétét. Ilyen módon könnyen megkerülhető több pillanatkép létrehozása.

2. A kellékek tesztelése

A kellékek tesztelését rendszerint két tesztre osztom:

  • Először ellenőrizze az alapértelmezett prop értékek megjelenítését. Amikor az összetevő megjelenítésre kerül, várhatóan az érték megegyezik az defaultProps értékével, ha ez a prop alapértelmezett.
  • Másodszor, ellenőrizze a prop egyéni értékét. Meghatározom a saját értékét, és azt várom, hogy azt az alkatrész megújítása után megkapják.

3. Adattípusok tesztelése

Annak kipróbálására, hogy milyen típusú adatok jönnek a kellékekben, vagy hogy milyen típusú adatokat kapunk bizonyos műveletek után, használhatjuk a jest-kiterjesztett (Extra Jest illesztők) speciális könyvtárat, amelynek kibővített egyezése van, amely hiányzik a Tréfa. Ezzel a könyvtárral az adattípusok tesztelése sokkal könnyebb és élvezetesebb.

A propipetípusok tesztelése ezzel szemben ellentmondásos kérdés. Egyes fejlesztők vitathatják a propotípusok tesztelését, mert ez egy harmadik fél csomagja, ezért nem szabad tesztelni. Mégis ragaszkodom az alkatrészek propipeinek teszteléséhez, mivel nem teszteljük maga a csomag működését. Ehelyett csak gondoskodom arról, hogy a próba típusok helyesek legyenek. Az adattípus nagyon fontos programozási rész, ezért nem szabad átugorni.

4. Események tesztelése

Miután készített egy pillanatfelvételt és lefedette a kellékeket a tesztekkel, biztos lehet benne, hogy az összetevő helyesen fog megjelenni. De ez nem elég a teljes lefedettséghez abban az esetben, ha események vannak az összetevőben.

Az eseményt többféle módon ellenőrizheti. A legelterjedtebbek a következők:

  • ál esemény => szimulálni => várható esemény hívása
  • ál esemény => esemény szimulálása paraméterekkel => várható esemény hívása átmenő paraméterekkel
  • át kell adni a szükséges kellékeket => render komponent => esemény szimulálása => egy bizonyos viselkedést várhat a meghívott eseménynél

5. Tesztelési feltételek

Nagyon gyakran lehet feltételeket egy adott osztály kiadására, a kód egy bizonyos szakaszának megjelenítésére, a szükséges kellékek átvitelére stb. Ne felejtsd el ezt, mert az alapértelmezett értékekkel csak az egyik ág felel meg a tesztnek, míg a második nem tesztelve.

Komplex összetevőkben, számításokkal és sok feltétellel hiányozhat néhány ága. Annak ellenőrzése érdekében, hogy a kód minden részét lefedik-e a tesztek, használjon tesztfedezeti eszközt, és szemrevételezéssel ellenőrizze, melyik ágakat takarja le és melyeket nem.

6. Tesztelési állapot

Az állapot ellenőrzéséhez a legtöbb esetben két tesztet kell írni:

  • Az első ellenőrzi az aktuális állapotot.
  • A második esemény ellenőrzése után ellenőrzi az állam állapotát. Megjelenít komponens => hívás funkció közvetlenül a tesztben => ellenőrizze, hogy az állapot megváltozott. Az összetevő függvényének meghívásához be kell szereznie az összetevő egy példányát, és csak akkor kell meghívnia annak módszereit (a példát a következő teszt mutatja).

Miután átnézett ezen utasítások listáján, az Ön alkotóeleme 90-100% -ot fedezi. 10% -ot hagyok olyan különleges esetekre, amelyeket a cikk nem írt le, de amelyek előfordulhatnak a kódban.

Példák tesztelésre

Térjünk át a példákra, és fedjük le az összetevőket tesztekkel, ahogy fentebb leírtuk lépésről lépésre.

1. Komponens tesztelése űrlapokból / bemenetekből.

Vegye ki az egyik összetevőt az űrlapok / bemenetek könyvtárából. Legyen a DateInput.js, a datepicker mező összetevője.

Kódlista a tesztelt alkatrészhez: DateInput.js
Úgy néz ki, mint a:

A DateInput összetevő a könyvtár react-datepicker-t használja, két segédprogrammal:

  • valueToDate (konvertálja az értéket dátumra)
  • dateToValue (a dátumot értékre konvertálja)

A csomag a dátummal való manipulációra, a PropTypes pedig a React kellékek ellenőrzésére.

Az összetevőkód szerint láthatjuk az alapértelmezett kellékek listáját, amelyek elősegítik az összetevő megkönnyítését:

const defaultProps = {
    inputClassName: 'input-custom',
    Megjelenített hónapok: 1,
    dateFormat: „HH.HH.ÉÉÉ”,
    showMonthYearsDropdowns: false,
    minDate: moment ()
};

Az összes támaszpont megfelelő a pillanatkép készítéséhez, kivéve egyet: minDate: moment (). A moment () megadja nekünk az aktuális dátumot minden egyes teszt futtatásakor, és a pillanatkép sikertelen lesz, mert elavult dátumot tárol. A megoldás az, hogy gátolja ezt az értéket:

const defaultProps = {
    minDate: pillanat (0)
}

MinDate prop-re van szükség minden megjelenített komponensben. A kellékek megkettőzésének elkerülése érdekében HOC-t hozok létre, amely az alapértelmezettProps-ot kapja, és egy szép összetevőt ad vissza:

importálja a TestDateInput fájlt a '../DateInput' fájlból;
const DateInput = (kellékek) =>
    ;

Ne felejtsük el a pillanat-időzónát, különösen, ha a teszteket más országbeli fejlesztők fogják elvégezni egy másik időzónában. Megkapják a gúnyolódott értéket, de időzóna eltolással. A megoldás egy alapértelmezett időzóna beállítása:

const moment = igény.requireAktuális ('momentum-időzóna'). tz.setDefault ('America / Los_Angeles')

Most a dátumbeviteli elem készen áll a tesztelésre:

1.Készítsen elő pillanatfelvételt:

it ('helyesen jeleníti meg a dátumösszetevőt', () => {
    const DateInputComponent = renderer.create () .JSON ();
    számíthat (DateInputComponent) .toMatchSnapshot ();
});

2.A kellékek tesztelése:

Nézze át a kellékeket és keresse meg a fontosokat. Az első tesztelhető prop: showMonthYearsDropdowns. Ha igaz, akkor a hónap és az évek legördülő menüje jelenik meg:

it ('ellenőrizze a megjelenő hónap és évek legördülő menüit', () => {
    const kellékek = {
            showMonthYearsDropdowns: igaz
        },
        DateInputComponent = beillesztés ().find('.datepicker ');
    számíthat (DateInputComponent.hasClass (reagálnak-datepicker elrejtés hónapos)). toEqual (true);
});

Tesztelje a null prop értéket. Ez az ellenőrzés annak biztosításához szükséges, hogy az összetevő meghatározott érték nélkül jelenjen meg:

it ('helyesen jeleníti meg a dátumot null értékkel', () => {
    const kellékek = {
            érték: null
        },
        DateInputComponent = csatlakoztatás ();
    számíthat ((DateInputComponent) .prop ( 'érték')). toEqual (null);
});

3.Tesztelje az értéket, a várakozás dátuma:

it ('ellenőrizze az érték típusát', () => {
    const kellékek = {
            érték: '08 .03.2018 '
        },
        DateInputComponent = csatlakoztatás ();
    számíthat (DateInputComponent.prop ( 'érték')). toBeString ();
});

4.Tesztesemények:

Először ellenőrizze az onChange eseményt.

  • mock onChange visszahívás módosítása
  • render dátum beviteli komponens
  • szimulálja a változás eseményét új célértékkel
  • és végül ellenőrizze, hogy az onChange esemény új értékkel lett-e meghívva.
it ('ellenőrizze az onChange visszahívást', () => {
    const onChange = jest.fn (),
        kellékek = {
            érték: „2018.01.20”,
            onChange
        },
        DateInputComponent = beépítés ().find('input ');
    DateInputComponent.simulate ('változás', {cél: {érték: pillanat ('2018-01-22')}});
    számíthat (onChange) .toHaveBeenCalledWith ('22 .01.2018' );
});

Ezután ellenőrizze, hogy a dátumválasztó felbukkanó ablak megnyílik-e a dátumbevitelre való kattintás után. Ehhez keresse meg a dátumbevitelt => szimulálja a kattintási eseményt =>, és várjon felugrást, amikor az .react-datepicker osztály jelen van.

it ('ellenőrizze a DatePicker felugró ablakának megnyitását', () => {
    const DateComponent = csatlakoztatás (),
        dateInput = DateComponent.find ("input [type = 'text']");
    dateInput.simulate (klikk);
    számítunk (DateComponent.find ( 'reagálnak-datepicker')). toHaveLength (1);
});

Teljes tesztlista: DateInput.test.js

2. Hasznos tesztelés:

Kódlista a tesztelt segédprogramhoz: valueToDate.js

Ennek a segédprogramnak az a célja, hogy egy értéket egy dátumra alakítson egy egyéni formátummal.

Először elemezzük az adott segédprogramot, és határozzuk meg a tesztelés fő eseteit:

  1. Ennek a segédprogramnak a célja szerint átalakítja az értéket, ezért ellenőriznünk kell ezt az értéket:
  • Ha az érték nincs meghatározva: Biztosítanunk kell, hogy a segédprogram nem ad vissza kivételt (hiba).
  • Ha érték van meghatározva: ellenőriznünk kell, hogy a segédprogram visszatér-e a pillanat dátumát.

2. A visszatért értéknek a pillanat osztályba kell tartoznia. Ezért kell egy pillanat példányának lennie.

3. A második argumentum a dateFormat. Állítsa állandóra a tesztek előtt. Ezért kerül át az egyes tesztekben, és a dátum formátumának megfelelő visszatérési értéket kap. Kell-e külön vizsgálnunk a dateFormat-ot? Azt hiszem, nem. Ez az érv választható - ha nem állítjuk be a dateFormat formátumot, akkor a segédprogram nem szakad meg, és csak a dátumot adja vissza alapértelmezett formátumban. Ez egy pillanatnyi munka, nem szabad tesztelnünk harmadik fél könyvtárait. Mint már említettem, nem szabad elfelejteni a pillanat-időzónát; ez egy nagyon fontos pont, különösen a különféle időzónákból származó fejlesztők számára.

Nézzük a kódot:

  1. Írja le az első eset tesztjét. Ha nincs értékünk, akkor az üres.
const formátum = 'NN.HH.ÉÉÉÉ';
it ('render valueToDate segédprogram üres értékkel', () => {
    const value = valueToDate ('', formátum);
    számíthat (érték) .toEqual (null);
});

2. Ellenőrizze, hogy van-e megadva érték.

const date = '21.11.2015 ',
      formátum = 'NN.hh.ÉÉÉÉ';
it ('render valueToDate segédprogram meghatározott értékkel', () => {
    const value = valueToDate (dátum, formátum);
    várható (érték) .toEqual (pillanat (dátum, formátum));
});

3. Ellenőrizze, hogy az érték tartozik-e a pillanatosztályhoz.

const date = '21.11.2015 ',
    formátum = 'NN.HH.ÉÉÉÉ';
it ('az érték egy pillanat példánya', () => {
    const value = valueToDate (dátum, formátum);
    várható (pillanat értékpéldánya) .toBeTruthy ();
});

A tesztek teljes listája: valueToDate.test.js

3. A kütyü tesztelése

A kütyü teszteléséhez fonókomponenst vettem.

Kódlista a tesztelt widgethez: Spinner.js

Így néz ki:

A forgatáshoz nincs szükség a magyarázatban, mivel szinte az összes webes erőforrás rendelkezik ezzel az összetevővel.

Tehát, ha teszteket írunk:

  1. Első lépés - pillanatkép létrehozása:
it ('helyesen teszi meg a Spinner komponenst', () => {
   const SpinnerComponent = rögzítés ();
   számíthat (SpinnerComponent) .toMatchSnapshot ();
});

2. A kellékek tesztelése:

Először nézzük meg az alapértelmezett prop címet, és ellenőrizzük, hogy helyesen jelenik-e meg.

it ('alapértelmezés szerint ellenőrizze a prop címet', () => {
 const SpinnerComponent = rögzítés ();
    várni (SpinnerComponent.find ('p'). text ()). toEqual ('Kérem várjon');
});

Ezután ellenőrizzük az egyéni prop címet. Ellenőriznünk kell, hogy visszatér-e a helyesen meghatározott prop. Vessen egy pillantást a kódra, a cím be van csomagolva a rawMarkup util fájlba, és a kimenetek a veszélyesenSetInnerHTML tulajdonság segítségével.

Kódlista a rawMarkup util számára:

alapértelmezett függvény exportálása a rawMarkup (sablon) {
    return {__html: sablon};
}

Be kell vonnunk a rawMarkup teszteket a fonó komponensbe? Nem, ez egy külön segédprogram, és a fonógéptől elkülönítve kell tesztelni. Nem érdekli, hogy működik - csak tudnunk kell, hogy a címsugár helyes eredményt ad.

Pontosítás: A pavojlySetInnerHTML tulajdonság használatának oka a következő. Webhelyünk többnyelvű, amelyért a fordítási marketing csapat felel. Lefordíthatják egyszerűen szavak kombinációjával, vagy akár HTML-címkékkel díszíthetik, például a , , , vagy akár szeletelhetnek szöveget a

    ,
      listákkal. Nem tudjuk biztosan, hogyan fordítják és díszítik a szöveget. Csak ezeket kell rendesen megjeleníteni.

      Két teszt esetet kombináltam egy tesztben:

      • visszaadja a helyes egyedi címet
      • helyesen jelenítse meg a prop címet HTML-címkékkel
      it ('ellenőrizze a prop címet html címkékkel', () => {
          const kellékek = {
                  cím: ' kérem várjon '
              },
              SpinnerComponent = rögzítés ();
          várni (SpinnerComponent.find ('p'). text ()). toEqual ('Kérem várjon');
      });

      Vegye ki a következő prop feliratot. Ez választható, és ezért nincs alapértelmezett támaszpontja, ezért hagyja ki a lépést az alapértelmezett kellékekkel és tesztelje az egyéni kellékeket:

      • Ellenőrizze, hogy a subTitle prop szöveg helyesen jelenik-e meg:
      const kellékek = {
              felirat: 'maradt 1 perc'
          },
          SpinnerComponent = rögzítés ();
      it ('helyes szöveget jelenít meg', () => {
          számítunk (SpinnerComponent.find ( 'P'). A (1) .text ()). toEqual (props.subTitle);
      });

      Tudjuk, hogy a felirat nem kötelező. Ezért ellenőriznünk kell, hogy nem a szeletelési jelölés szerint nem alapértelmezett kellékekkel jelenítik meg-e. Csak ellenőrizze a címkék számát

      :

      it ('ellenőrizze, hogy a felirat nem kerül megjelenítésre', () => {
        const SpinnerComponent = rögzítés ();
          számítunk (SpinnerComponent.find ( 'P'). hosszúság) .toEqual (1);
      });

      3.Kapcsolási típusok tesztelése:

      • A címsugár várhatóan karakterlánca:
      it ('ellenőrizze, hogy a cím típusa string-e', () => {
          const kellékek = {
                  cím: 'Várj'
              },
              SpinnerComponent = rögzítés ();
          számíthat (SpinnerComponent.find ( 'p'). text ()). toBeString ();
      });
      • A felirat prop esetében szintén várható, hogy string legyen:
      const kellékek = {
              felirat: 'maradt 1 perc'
          },
          SpinnerComponent = rögzítés ();
      it ('Az alcím típusa karakterlánc', () => {
          számítunk (SpinnerComponent.find ( 'P'). A (1) .text ()). toBeString ();
      });

      Teljes tesztlista: Spinner.test.js

      4. Modális tesztelés (ModalWrapper.js és ModalTrigger.js)

      Úgy néz ki, mint a:

      Hogyan teszteljük a modumokat?

      Mindenekelőtt el szeretném magyarázni, hogy a modálokat hogyan szervezik meg a projektünkön. Két összetevőnk van: ModalWrapper.js és ModalTrigger.js.

      A ModalWrapper felelős a felbukkanó elrendezésért. Tartalmazza a modális tartályt, a „bezárás” gombot, a modális címet és a testet.

      A ModalTrigger felelős a modális kezelésért. Magában foglalja a ModalWrapper elrendezését, és eseményeket tartalmaz a modális elrendezésének vezérlésére (nyitott és bezárott műveletek).

      Az egyes alkotóelemeket külön-külön áttekintem:

      1.Kódlista a tesztelt alkatrészhez: ModalWrapper.js

      Nézzük a kódot:

      Először a ModalWrapper veszi az összetevőt, és azt belső részre teszi. Először ellenőrizze, hogy a ModalWrapper az összetevő nélkül nem fog-e megbukni. Készítsen pillanatképet alapértelmezett kellékekkel:

      it ('összetevő nélkül', () => {
          const ModalWrapperComponent = sekély ();
          számíthat (ModalWrapperComponent) .toMatchSnapshot ();
      });

      A következő lépés a tényleges állapotának szimulálása a kellékekben átadott alkatrész-rendereléssel:

      it ('komponenssel', () => {
         const kellékek = {
                 összetevő: () => {}
              },
              ModalWrapperComponent = sekély ();
          számíthat (ModalWrapperComponent) .toMatchSnapshot ();
      });

      Kellékek tesztelése

      Egyéni osztálynév fogadása:

      it ('helyes osztálynevet adni', () => {
          const kellékek = {
                  modalClassName: 'custom-class-name'
              },
              ModalWrapperComponent = sekély ().find('Modal ');
              számíthat (ModalWrapperComponent.hasClass (rendelésre class-name ')). toEqual (true);
      });

      Egyéni címprogram fogadása:

      it ('helyes címet adni', () => {
          const kellékek = {
                 cím: „modális cím”
             },
             ModalWrapperComponent = sekély ().find('ModalTitle ');
          várható (ModalWrapperComponent.props (). gyermekek) .toEqual ('Modális cím');
      });

      Helyes show-javaslat fogadása:

      it ('check prop value', () => {
              const kellékek = {
                     show: igaz
                 },
                 ModalWrapperComponent = sekély ().find('Modal ');
              számíthat (ModalWrapperComponent.props (). Show) .toEqual (true);
          });

      Proptidek tesztelése

      • A show prop
      it ('check prop type', () => {
          const kellékek = {
                 show: igaz
              },
              ModalWrapperComponent = sekély ().find('Modal ');
          számíthat (ModalWrapperComponent.props (). Show) .toBeBoolean ();
      });
      • Az onHide prop számára
      it ('helyes onHide-prop típusúvá tétele', () => {
          const kellékek = {
                  onHide: () => {}
              },
              ModalWrapperComponent = sekély ().find('Modal ');
          számíthat (ModalWrapperComponent.props (). onHide) .toBeFunction ();
      });
      • Komponens prop
      it ('helyes komponens-támasz típusának renderelése', () => {
         const kellékek = {
                 összetevő: () => {}
             },
             ModalWrapperComponent = rögzítés ();
         számíthat (ModalWrapperComponent.props (). komponens) .toBeFunction ();
      });

      Teljes tesztelés: ModalWrapper.test.js

      2.Kódlista a tesztelt alkatrészhez: ModalTrigger.js

      A modális burkolatot lefedték egy teszttel. A második rész a modális ravaszt alkotóelem fedezésére szolgál.

      Az alkotóelemek áttekintése: az átváltott állapoton alapul, amely jelzi a ModalWrapper láthatóságát. Ha váltás: hamis, a felugró ablak rejtett, egyébként látható. Az open () funkció megnyitja a felbukkanó elemet a gyerek elemnél. A kattintási esemény és a funkció bezárása () elrejti a felbukkanó gombot a ModalWrapperben megjelenített gombra.

      Pillanatkép készítése:

      it ('helyesen jeleníti meg a ModalTrigger komponenst', () => {
          const ModalTriggerComponent = sekély ( 
      );     számíthat (ModalTriggerComponent) .toMatchSnapshot (); });

      Kell-e tesztelnünk a ModalTrigger-et komponens prop megjelenítéssel? Nem - mert az összetevő a ModalWrapper összetevőn belül jelenik meg. Nem függ a tesztelt alkatrésztől. Ezt már lefedték a ModalWrapper tesztek során.

      Kellékek tesztelése:

      Egy prop gyerekünk van, és biztosak akarunk lenni abban, hogy csak egy gyermekünk van.

      it ('biztosítson, hogy csak egy gyermek legyen (vezérlőelem)', () => {
          várható (ModalTriggerComponent.findWhere (node ​​=> node.key () === 'modal-control'). hossz) .toEqual (1);
      });

      Proptidek tesztelése:

      A gyermektámasznak tárgynak kell lennie, ezért ellenőrizze ezt a következő tesztben:

      const ModalTriggerComponent = csatlakoztatás ( 
      );
      it ('ellenőrizze a gyermekek támasztékának típusát', () => {
            számíthat (ModalTriggerComponent.props (). gyermek) .toBeObject ();
      });

      A ModalTrigger komponens fontos része az állapotok ellenőrzése.

      Két állapotunk van:

      • Megnyílik a felbukkanó ablak. Ahhoz, hogy tudjuk, hogy a modális megnyílik, ellenőriznünk kell annak állapotát. Ehhez hívja meg a nyitott függvényt az összetevő példányából, és várja meg, hogy az átkapcsolt állapotban igaz legyen.
      it ('ellenőrizze, hogy a modál nyitva van-e', () => {
          const esemény = {
              prevenDefault: () => {},
              stopPropagation: () => {}
          };
          ModalTriggerComponent.instance (). Open (esemény);
          számíthat (ModalTriggerComponent.state (). billentve) .toBeTruthy ();
      });
      • A felugró ablak bezárva. Tesztelték fordítva, az átkapcsolt állapotnak hamisnak kell lennie.
      it ('ellenőrizze, hogy a modál zárva van', () => {
         ModalTriggerComponent.instance (). Bezár ();
         számíthat (ModalTriggerComponent.state (). billentve) .toBeFalsy ();
      });

      Teljes tesztlista: ModalTrigger.test.js

      Most a modálokat teljes mértékben tesztelték. Egyetlen tanács az egymástól függő összetevők teszteléséhez: először nézze át az összetevőket és írja be a teszttervet, határozza meg, hogy mit kell tesztelnie az egyes összetevőkben, ellenőrizze az egyes összetevők tesztjeit, és ügyeljen arra, hogy ne ismételje meg ugyanazt a teszt esetet mindkét alkotóelemnél. Gondosan elemezze a lehetséges és optimális változatokat a teszt lefedettségéhez.

      5. HOC tesztelés (magasabb rendű alkatrész)

      Az utolsó két rész (HOC és az űrlapmezők tesztelése) összekapcsolódik. Szeretném megosztani veled a terepi elrendezés tesztelését annak HOC-jával.

      Itt található egy magyarázat arról, hogy mi a BaseFieldLayout, miért van szükségünk erre az összetevőre, és hol használjuk?

      • A BaseFieldLayout.js az űrlap-beviteli komponensek csomagolása, például a TextInput, a CheckboxInput, a DateInput, a SelectInput stb. Azok nevei az -Input szóval zárulnak, mert redux-form csomagot használunk, és ezek az összetevők a redux-forma logika bemeneti elemei.
      • Szükségünk van BaseFieldLayout-ra az űrlapmezők alkotóelemeinek elrendezéséhez, azaz címke, eszköztippek, előtagok (pénznem, négyzetméteres rövidítések stb.), Ikonok, hibák és így tovább megjelenítéséhez.
      • A BaseFieldHOC.js fájlban felhasználjuk az inputComponent becsomagolására a mező elrendezésében és a redux-formához való összekapcsoláshoz a összetevő segítségével.

      Kódlista a tesztelt alkatrészhez: BaseFieldHOC.js

      Ez egy HOC, amely megkapja az űrlap bemeneti összetevőjét, és visszaadja az összetevőt, redux-formával összekapcsolva.

      A HOC elemzése:

      • Ez az elem csak egy prop, komponenst kap. Először is el kell készítenem ezt az összetevőt, és be kell csomagolni a BaseFieldHOC-ba.
      • Ezután be kell csomagolni a becsomagolt HOC-t redux-formával, hogy a mező összekapcsolódjon redux-formával.
      • Rendeld el ezt a mezőt a React Redux összetevőn belül, hogy az áruház elérhető legyen a tesztelt összetevő számára. Az áruház gúnyolódásához tegye a következőket:
      const store = createStore (() => ({}));

      Most, minden teszt előtt, a következőket kell tennem:

      engedje BaseFieldHOCComponent;
      beforeEach (() => {
          const TextInput = () => {return 'text input'; },
              BaseFieldHOCWrapper = BaseFieldHOC (TextInput),
              TextField = reduxForm ({képernyő: 'testForm'}) (BaseFieldHOCWrapper);
          BaseFieldHOCComponent = renderer.create (
              
                  
              
          ) .ToJSON ();
      });

      Ezután az alkatrész készen áll a tesztelésre:

      1. Pillanatkép létrehozása:
      it ('helyesen rendereljük az összetevőt', () => {
          számíthat (BaseFieldHOCComponent) .toMatchSnapshot ();
      });

      2. Győződjön meg arról, hogy a bemeneti összetevő be van csomagolva a BaseFieldLayoutbe a megjelenítés után:

      it ('ellenőrizze, hogy a bemeneti összetevő be van-e csomagolva a BaseFieldLayout-ba', () => {
          számítunk (BaseFieldHOCComponent.props.className) .toEqual ( 'forma-csoport');
      });

      Ez minden, a HOC le van fedve. A redux-formához kapcsolódó komponensek tesztelésének legbonyolultabb része a mező előkészítése (díszítés redux formával és setup áruház). A többi egyszerű, csak kövesse az utasításokat és semmi mást.

      A tesztek teljes listája: BaseFieldHOC.test.js

      6. Űrlapok / mezők tesztelése

      A HOC mezőt tesztek borítják, így továbbléphetünk a BaseFieldLayout komponensre.

      A tesztelt alkotóelem kódja: BaseFieldLayout.js

      Kódoljuk a BaseFieldLayout.js kódot, és írjuk fel a teszteket a fenti utasítások szerint:

      1. Először is készítsen pillanatfelvételt.

      Ezt az összetevőt nem jelenítik meg az defaultProps nélkül:

      • inputComponent
      • A redux-form által biztosított kellékek: input és meta objektumok. Bevitel tulajdonságnévvel és meta tulajdonságokkal kapcsolatos hibával és megérintéssel:
      const defaultProps = {
         meta: {
              megérintette: null,
              hiba: null
          },
          input: {
              név: 'mezőnév'
          },
          inputComponent: () => {visszatér 'teszt eset'; }
      }

      Az defaultProps használatához az egyes tesztelt csomagolókban tegye a következőket:

      importálja a TestBaseFieldLayout programot a '../BaseFieldLayout' webhelyről;
      const BaseFieldLayout = (kellékek) => ;

      Most készen állunk pillanatkép készítésére:

      it ('helyesen jeleníti meg a BaseFieldLayout komponenst', () => {
          const BaseFieldLayoutComponent = renderer.create () .JSON ();
          számíthat (BaseFieldLayoutComponent) .toMatchSnapshot ()
      });

      2. A kellékek tesztelése:

      Ennek az összetevőnek sok kelléke van. Több példát mutatok be, a többit analógia útján teszteljük.

      • Győződjön meg arról, hogy a prop ikon helyesen jelenik meg
      it ('helyesen jeleníti meg az ikonra mutató prop' -t, () => {
          const kellékek = {
                  ikon: 
              },
              BaseFieldLayoutComponent = csatlakoztatás ();
              számíthat (BaseFieldLayoutComponent.find (span). hasClass (ikon felkiáltójellel)). toBeTruthy ();
      });
      • Győződjön meg arról, hogy az eszköztipp tartalma megjelenik a címke mellett
      const kellékek = {
              labelTooltipContent: 'címke eszköztipp'
          },
          BaseFieldLayoutComponent = csatlakoztatás ();
      it ('check prop rendered', () => {
         számíthat (BaseFieldLayoutComponent.find (span). hasClass (tooltip-icon ')). toBeTruthy ();
      });
      • A fieldLink prop tesztelése
      • Győződjön meg arról, hogy a fieldLink alapértelmezés szerint nulla
      it ('ellenőrizze, hogy a prop alapértelmezés szerint nulla', () => {
          const BaseFieldLayoutComponent = sekély ();
          számíthat (BaseFieldLayoutComponent.props (). fieldLink) .toBe (null);
      });
      • Győződjön meg arról, hogy a fieldLink helyesen jelenik meg az egyedi értékkel

      3. Tesztelési hibák:

      it ('ellenőrizze, hogy a mezőben nincs-e hiba', () => {
          const kellékek = {
                  meta: {
                      megható: igaz,
                      hiba: 'A mező kitöltése kötelező'
                  }
              },
              BaseFieldLayoutComponent = csatlakoztatás ();
          számíthat (BaseFieldLayoutComponent.find ( '. error)). toHaveLength (1);
      });

      A tesztek teljes listája: BaseFieldLayout.test.js

      Alsó sor

      Most már tudja, hogyan kell elvégezni az összetevők teljes lefedettségének tesztelését a projekt felépítése alapján. Saját tapasztalataim alapján megpróbáltam elmagyarázni, hogy mi szükséges a teszteléshez, milyen sorrendben és mit hagyhat ki a teszt lefedettségében. Ezenkívül bemutattam több tesztelő komponens példáit és felismertem a kódbázis lefedettségének sorrendjét.

      Remélem, hogy hasznosnak találja ezt a cikket, és megosztja a válaszokat. Köszönöm hogy elolvastad.

      Ha hasznosnak találja ezt a bejegyzést, érintse meg az alábbi gombot :)