js tesztelése. JavaScript tudásteszt – alapok

Egyik barátom értetlenségét fejezte ki egyszer, hogy a JavaScript segítségével egyáltalán lehet komoly vállalati termékeket írni, mert nincs fordítója. Valójában a jó minőségű kód létrehozásában semmiképpen sem az a döntő szerepe, hogy egy programozási nyelvhez van fordítóprogram, hanem egy szoftverrendszer létrehozásának megfelelően megválasztott és jól hangolt technikai folyamata.

Ennek a folyamatnak tartalmaznia kell egy sor minőség- és hatékonyság-ellenőrző eszközt a programozó számára. Ilyen eszközök lehetnek: egység- és integrációs tesztelés, folyamatos integráció (Continuous Integration, CI), különféle mérőszámok összegyűjtése és elemzése (például nagyon hosszú módszerek az nDependben), a JsLint, FxCop követelményeinek való megfelelés ellenőrzése stb.

Ebben a cikkben szeretném elmondani, hogyan kell megfelelően végrehajtani a termék automatikus egység- és integrációs tesztelését JavaScriptben. Valójában a JavaScript ebben a tekintetben nem különbözik a Java-tól vagy a C#-tól.

Agilis, TDD és BDD

Általában javasolt automatikus egység- és integrációs tesztek létrehozása a végrehajtott funkcionalitáshoz, hogy csökkentse a regressziós hibák kockázatát a kód későbbi megváltoztatásakor. A JavaScript esetében ezek a tesztek sokkal könnyebbé tehetik annak ellenőrzését, hogy a rendszer különböző böngészőkön keresztül működik-e azáltal, hogy automatizálják a működését biztosító lépéseket. Emellett jó szolgálatot tehet, ha a termék minden lezárt hibájához egy egység- vagy integrációs tesztet ír.

Vannak olyan programozási technikák is, amelyek megkövetelik a kódolás logikáját egy egységteszt megírásával: Tesztvezérelt fejlesztés (TDD) és Behavior-Driven Development (BDD). Gyakran használják az Agilis folyamatban. Tekintsük részletesebben jellemzőiket.

Tesztvezérelt fejlesztés

A tesztvezérelt fejlesztés egy iteratív kódolási folyamat, amely megismétli a következő négy lépést:

1. lépés. Mielőtt új logikai elemet adna hozzá, hozzon létre egy egységtesztet a logika tesztelésére;

2. lépés. Futtassa le a tesztet, és győződjön meg róla Nem passzol;

3. lépés. Írja meg a legegyszerűbb kódot, amely sikeressé teszi a tesztet;

4. lépés. Szerkessze a kódot a minőségi követelményeknek megfelelően, távolítsa el a kód ismétlődését, és győződjön meg arról, hogy a teszt sikeres.

Az egységteszt egy olyan kód, amely valamely összetevő (modul) működését teszteli izolált környezetben. Az integrációs teszt egy olyan kód, amely tesztel közös munka több komponens. A tesztkettős tesztek egy modul izolált környezetben történő tesztelésére szolgálnak, ha az más moduloktól függ.

Teszt kettős

Az egységtesztelésnél használt segédobjektumok kategóriákra való felosztása Gerard Mészáros xUnit Test Patterns című könyvéből származik. Ezeket a kategóriákat összefoglaló néven "tesztpárosoknak" (tesztpárosoknak) nevezik. A duplázók a következő típusúak:

  • hamisítvány;
  • Színlelt.

Stub kimeneti értékek amelyekre előre be van állítva. Egy függő komponens interfészének utánzására szolgál.

Mock egy segítő objektum viselkedés ami előre be van állítva. Egy függő komponens interfészének utánzására és annak tesztelésére szolgál, hogy helyesen használják-e a teszt során.

Kém egy segítő objektum az elnevezett metódusok és a teszt során átadott paraméterek ellenőrzéséhez.

Hamisítvány egy segédobjektum, amely egy függő komponens interfészét valósítja meg egyszerűsített formában. Például egységtesztelési célokra a termék éles verziójában használt relációs adatbázis helyett egy memórián belüli adatbázis is lehet.

Színlelt egy segítő objektum, amelynek jelzését vagy átadását a metódus aláírása vagy bármely más szerződés megköveteli, de a tényleges érték soha nem kerül felhasználásra.

A Stub és a Mock közötti különbség a teszteredmények ellenőrzésének módja. Stub esetén az objektum állapotát a teszt végén ellenőrizzük. Mock esetén a teszt ellenőrzi, hogy az objektumot pontosan a regisztráció során leírtak szerint használják-e. Részletek megtalálhatók Martin Fowler Mocks Aren "t Stubs jegyzetében, és csak egy példát mutatok be.

Stub Mock
"a tesztelésnek meg kell kezdenie a lekérdezést": function () ( this.client.url = "/my/url"; sinon.stub(ajax, "poll").returns(()); this.client.connect(); sinon.assert.chedWith(ajax.poll, "/my/url"); ) "a tesztelésnek el kell indulnia a lekérdezésnek": function () ( this.client.url = "/my/url"; var mock = sinon.mock(ajax) mock.expects("poll") .withArgs("/my/url" ").returns(()); this.client.connect(); mock.verify(); )

Viselkedésvezérelt fejlesztés

A fejlesztés iteratív megközelítése szoftver funkcionális követelmények megvalósításán keresztül – ez a már megszokott tesztvezérelt, eredményközpontú fejlesztési stílus. A következő három lépést követi egymás után a BDD folyamat:

1. lépés. A megvalósított modul funkcionális követelményeinek meghatározása tesztek formájában;

2. lépés. Modul kódolás;

3. lépés. A futtatott tesztek eredményeinek ellenőrzésével ellenőrizheti, hogy az ügyfél vagy az üzleti elemző () minden kívánsága teljesül-e.

A BDD stílusban végzett tesztek írásakor nagyon kényelmes a Mock objektumok használata, mivel ezek tökéletesen tükrözik az összetevő funkcionális követelményeit. Így a BDD folyamatban a tesztek a feladat formalizált reprezentációjaként szolgálhatnak ( felhasználói történet) értelemben Dulakodás, amely lehetővé teszi, hogy időt takarítson meg a késztermék műszaki leírásának és dokumentációjának megírására.

Mi legyen a JavaScript egységtesztelési keretrendszer?

A teljes JavaScript-egységnek és az integrációs tesztelőeszköznek a következő összetevőkből kell állnia:

  • Állítási könyvtár (a komponens állapotának ellenőrzésére szolgáló módszerek összessége az egyes tesztek végén);
  • Mock library (ál-objektumok és egyéb "alsótanulmányok" generálására szolgáló eszköz);
  • Tesztfutó (műszer Automatikus indítás tesztek a legtöbb böngésző támogatásával, beleértve az iOS és Android böngészőket is);
  • Csatlakozási blokk a folyamatos integráció népszerű rendszereihez (Continuous Integration).

JavaScript egység tesztelési stratégiák

Ma három stratégia létezik a JavaScript-kód egységtesztelésére (további részletekért lásd Christian Johansen Test-Driven JavaScript Development című könyvének harmadik fejezetét):

  • böngészőben tesztelés;
  • fejetlen tesztelés;
  • Tesztelés útközben JsTestDriver.

A böngészőn belüli tesztelés magában foglalja az összes egység- és integrációs teszt futtatását egy HTML-oldalról, amelyet a fejlesztő saját maga nyit meg a szükséges böngészőkben. Ez a megközelítés egyszerű és intuitív. Hátránya azonban, hogy nem teszi lehetővé az ilyen tesztek folyamatos integrációba való bevonását. Ezenkívül egy HTML-oldal manuális elindítása tíz vagy több böngészőben, és az „F5” folyamatos lenyomása unalmas lehet a fejlesztő számára.

A fej nélküli tesztelés azt jelenti, hogy minden JavaScript kódot egy emulátoron tesztelnek, amely Java, Ruby, JavaScript, C++ stb. nyelven írható. A leghíresebb emulátor messze a PhantomJS, amely a webkit, innen indult parancs sor. Az emulátor előnyei közül kiemelhető, hogy könnyen használható a Folyamatos Integrációban, valamint az is, hogy lehetővé teszi az összes teszt indításának automatizálását parancssorból. Ennek a megközelítésnek azonban van egy jelentős hátránya - a kódot nem tesztelik valódi böngészőkön, így fennáll annak a veszélye, hogy hiányzik a böngészőhibák, amelyek nem reprodukálódnak az emulátoron. A JsTestDriver megjelenése előtt gyakran láthatta a böngészőn belüli tesztelést fej nélküli teszteléssel kombinálva, mivel ezek olyan jól kiegészítik egymást.

A tesztelés a szoftverfejlesztési ciklus szerves része. A kezdő fejlesztőcsapatok gyakran alábecsülik a szerepét, és a régi módon ellenőrzik az alkalmazás teljesítményét – „működik, és ez rendben van”. Előbb-utóbb ez a stratégia kudarcot vall, és a hibakövető elkezdi túlterhelni a feladatok számtalan seregét. Annak érdekében, hogy ne essünk ilyen csapdába, azt javaslom, egyszer s mindenkorra foglalkozzon a JavaScript kód tesztelésének árnyalataival.

A JavaScript már nem torta!

Azt hiszem, nem kell elmagyaráznom, hogy a JavaScript ma már nem csak egy nyelv a dolgok fűszerezésére. kinézet alkalmazások. De azért elmagyarázom, és egy kis bemutatkozást teszek, mert akkor többet fizetek több pénz! 🙂 Tehát azok az idők, amikor a JavaScriptet viccekhez vagy menük készítéséhez használták, örökre elmúltak. Most ez egy független nyelv, amely egyformán jól működik mind a kliensen, mind a szerveren. Jelentősen megnőtt a JavaScript szerepe, ami azt jelenti, hogy kódíráskor nem szabad félni a más programozási nyelveken bevált gyakorlatoktól sem.

Mit értek gyakorlatok és paradigmák alatt? Természetesen az MVC (model view controller) architekturális minta és kódszervezési minták. Ha követi ezeket az egyszerű trükköket, jobb kódot írhat, amely nem csak könnyen karbantartható, hanem automatikusan tesztelhető is.

A jó tesztek szabályai

  • A tesztnek a lehető legegyszerűbbnek kell lennie. Minél nehezebb a teszt, annál valószínűbb, hogy hibázik.
  • A teszteket modulokba kell csoportosítani, hogy a későbbiekben könnyebben megtalálhassák a hibákat és lehessen tesztelni az alkalmazás egyes részeit.
  • Egyik teszt sem függhet más tesztektől.
  • Mindig írjon külön tesztet minden alkalommal, amikor hibát talál.

A legtöbb tesztelő hibája

Nem titok, hogy a tesztelés legnépszerűbb módja mindig is a banális szemvizsgálat volt. A lényege egyszerűen megszégyeníthető – írtam pár ezer soros kódot, megoldottam a problémát és elindítottam az alkotásomat. Játszottam, kattintgattam - úgy tűnik, minden működik, fel lehet tölteni a harci szerverre. Minden rendkívül egyszerű, és a fejlesztő (ideális esetben egy "tesztelő" becenevű egyén) kellő figyelmével bízhat az alkalmazás megfelelő működésében.

A gyakorlatban minden kicsit másképp történik. Általános szabály, hogy nincs külön tesztelő. A fejlesztő maga igyekszik ellenőrizni a program működőképességét a technikai feladatban meghatározott műveletsor végrehajtásával. A fejlettebb kódhamisítók automatizálják az ilyen típusú integrációs tesztelést olyan eszközökkel, mint a Selenium.

Így a programozó lehetőséget kap arra, hogy csak a legdurvább hibákat észlelje. Sajnos a "hülye" és "váratlan" felhasználói lépések, valamint az üzleti logika trükkös lépései az esetek 99%-ában a színfalak mögött maradnak.

A külön teszter jelenléte részben és bizonyos ideig megoldja a problémát. Még ha figyelmen kívül hagyjuk is a részletekre való odafigyelését, tesztelésének minősége az alkalmazás növekedésével a nullára csökken. Mondok egy példát a gyakorlatból.

Egyszer megbízást kaptam egy kis program kidolgozására. A projekt funkcionalitást tekintve a legegyszerűbb CRM-re hasonlított, amit a lehető legrövidebb idő alatt megvalósítottam. Miután megkaptam az esedékes díjazást, minden forrást átadtam a megrendelőnek, és nyolc hónapra megfeledkeztem a projektről. Aztán kezdődött a legérdekesebb. Az ügyfél úgy döntött, hogy komolyan bővíti a program funkcionalitását, és segítségért hívott. Természetesen fogtam és elkezdtem funkcióról funkcióra faragni... Eleinte nem volt nehéz, de amikor a funkcionalitás átfogó integrációjáról volt szó, zümmögő bug-raj rohant felém. A kóddarabok ütközni kezdtek, és sok időt kellett töltenem a konfliktusok megoldásával. – Nos, hogy nem vette észre, hogy probléma van a jelentkezésével? kérdezik majd az olvasók. Válaszolok: elindítottam, de az alkalmazás kinőttsége miatt egyszerűen nem volt időm és idegeim tömegesen tesztelni az összes funkcionalitást. Csak az egyes funkciók tesztelésére szorítkoztam, és nagyvonalúan fizettem érte. A történet morálja: "Gondoljon a tesztelésre a fejlesztés szerves részének."

Az egységtesztek olyanok, mint az ezüstgolyó

Az egységtesztelés a legjobb módja annak, hogy kímélje idegeit, és növelje a garanciákat arra, hogy az alkalmazás egyes részei működni fognak. Ha még soha nem találkozott ezzel a szörnyű állattal, akkor röviden elmagyarázom. Az egységtesztek lehetővé teszik a tesztelési folyamat automatizálását és az alkalmazás minden funkciójának tesztelését.

A fejlesztés befejezése után új funkció(lehetőség van tesztek írására a fejlesztés megkezdése előtt) a fejlesztő egy speciális kódot ír a kódjának tesztelésére. Különböző helyzeteket kell szimulálnia és értékeket kell visszaadnia. Például írtunk egy függvényt a szóközök levágására (trim). A teljesítmény teszteléséhez számos tesztet kell készítenünk, amelyek lehetővé teszik, hogy kijelenthessük, hogy:

  • a "string" karakterlánc átadásakor "string"-et kapunk kimenetként;
  • amikor a „9. sor” kifejezést adjuk át a kimeneten, „9. sort” kapunk;

Más beviteli paraméterek tesztelését is hozzáadhatjuk (például a szóköz karaktert tabulátorra cseréljük). Általánosságban elmondható, hogy minél jobban fedjük le a kódot tesztekkel, és minél jobban előre látjuk a lehetséges negatív lehetőségeket, annál nagyobb az esélye annak, hogy a legfontosabb pillanatban egy kis szőr marad a fejen.

A JS világában a teszteket általában speciális keretrendszerek segítségével írják. Mindent megvannak, ami ehhez szükséges, valamint néhány eszközt a teszt előrehaladási jelentések szervezéséhez.

Tesztek!= extra kód

A nem egységtesztelők szeretnek azzal érvelni, hogy az egységtesztelés írást és karbantartást igényel kiegészítő kód. Azt mondják, hogy a valódi projektekben a határidők leggyakrabban tömörítettek, és egyszerűen nem lehet további kódot írni.

Amikor nincs idő a tesztekre

Idő hiányában nincs értelme egyszerű függvényekre teszteket írni (a cikkben szereplő példából vegye ki ugyanazt a vágást ()), jobb, ha a kód legkritikusabb szakaszaira összpontosít. Ugyanezt a szabályt kell követni a gyakran változó kód írásakor. Az élő projektek feladatköre gyakran változik, és bizonyos funkciókat folyamatosan frissíteni kell. Az ilyen változások kellemetlen pillanatokhoz vezethetnek - a megváltozott kód jól működik az új adatokkal, de nem emészti meg szervesen a régieket. Itt, hogy ne akadjon fenn a feil, jobb azonnal ellenőrizni az ilyen funkciókat. Emlékezzen egy egyszerű szabályra: nincs idő az összes kódot tesztekkel lefedni - fedje le a legfontosabb részét.


Ami a szoros határidőket illeti, egyetértek, de kész vagyok vitatkozni az extra kóddal kapcsolatban. Egyrészt igen - a tesztek további kódot igényelnek, és ezért van idő annak megírására. Másrészt ez a kód a légzsák szerepét tölti be egy autóban, és az alkalmazás növekedésével mindenképpen kifizetődik.
  • Cristian Johansen tesztvezérelt JavaScript-fejlesztés (goo.gl/mE6Is) azon kevés könyvek egyike, amelyek tesztírási szempontból vizsgálják a JavaScriptet.
  • John Resing, Beer Bibo JavaScript Ninja Secrets (goo.gl/xquDkJ) egy jó könyv, amely elsősorban a középhaladó JS-fejlesztők számára lesz hasznos. A könyv részletesen tárgyalja a hatékony, böngészők közötti kód írásának kérdéseit, az eseménykezelés árnyalatait és sok más finomságot.
  • David Flanagan JavaScript. Teljes útmutató» (goo.gl/rZjjk) - A könyvet hatszor adták ki újra, és mindegyik kiadás bestsellernek számít. Valóban, ez a legtöbb részletes útmutató JavaScripten, amelyet minden JS-fejlesztőnek el kell olvasnia legalább egyszer.
  • PhantomJS + JSCoverage + QUnit vagy konzol JS egységtesztek lefedettség számítással (goo.gl/FyQ38) - a cikk szerzője bemutatja a fenti csomagok egy csomó használatát statisztikák gyűjtésére és a kódlefedettség százalékos tesztekkel történő kiszámítására.
  • Hasznos PhantomJS használati esetek – Ez az oldal számos PhantomJS harci felhasználást mutat be.

Ha nincs idő, és gyötrő a vágy, hogy megtagadja a tesztírást, gondoljon háromszor. Talán ebben az esetben célszerűbb lenne csak a kód legtrükkösebb részeit lefedni tesztekkel, ahelyett, hogy teljesen felhagynánk a teszteléssel. Mindig gondoljon a jövőre, mintha egy hónap alatt a programja soha nem látott méretűvé nőhetne.

Nem minden kódot tesztelnek

Miért mondom, hogy a fő kód megírása előtt át kell gondolni a tesztelést? Igen, mert az eredetileg egységteszteknek lefedett kód kissé más stílusban van megírva. Nem minden kód tesztelhető. A logikát és a reprezentációkat keverő kódot, sőt nem értem hova feltömve nem lehet normálisan tesztelni. Itt mindig azt tanácsolom, hogy kövessen néhány egyszerű szabályt:

  • Nem kell nagy függvényeket írni. Minden függvénynek egy problémát kell megoldania, nem pedig 100500 lehetséges helyzetet. Például nem kell leakasztani a kódot az adatok kiszolgálóra küldéséhez az előkészítésért felelős funkcióban.
  • A tíznél több soros kóddal rendelkező függvény valószínűleg rossz függvény.
  • A logika és a prezentáció soha nem járhat együtt.

QUnit - a műfaj klasszikusa a jQuery alkotóitól

A QUnit különösen népszerű a JavaScript-fejlesztők körében. Először is, jól dokumentált és könnyen használható, másodszor pedig a jQuery szerzői készítették. A könyvtár alkalmas jQuery alapú és natív JavaScript kód tesztelésére is.


Letöltés legújabb verzió QUnit megteheti a hivatalos webhelyről. A könyvtár egyetlen JS- és CSS-fájlként érkezik. Tegyük fel, hogy rájöttél, hogyan kell betölteni a szükséges komponenseket, és ha igen, akkor itt az ideje, hogy írj egy próbatesztet. Ne menjünk messzire, és próbáljuk meg tesztelni a trim() függvényt.

A tesztek bemutatására egy egyszerű projektet készítettem a következő szerkezettel:

  • index.html - a fő fájl, amely megjeleníti a teszteredményeket;
  • qunit-1.12.0.js - QUnit könyvtár fájl;
  • example.js - a teszteléshez szükséges kódot (esetünkben a trim() függvény leírását) tartalmazó fájl;
  • test.js - teszteket tartalmazó fájl;
  • qunit-1.12.0.css - stílusok tesztekkel készített jelentés készítéséhez.

Az index.html és a test.js fájl tartalma az 1. és 2. listában látható. A második lista, amely leginkább érdekel minket, a tesztelés alatt álló függvény deklarációja (trim()) és a működését ellenőrző tesztkód . Vedd figyelembe, hogy maga a trim() függvény bárhol elhelyezhető, csak azért tettem a második listába, hogy helyet spóroljunk a naplóban.
Most pedig nézzük magukat a teszteket. A QUnit.js könyvtár számos módszert kínál:

  • test() - wrapper a teszt leírásához;
  • ok() - az állítás lehetővé teszi az első paraméter igazságának ellenőrzését. Példánkban hívást adok neki az általunk definiált trim() függvénynek, és összehasonlítom a várható értékkel. Ha a feltétel igaz, a teszt sikeres;
  • egyenlő() - a módszer lehetővé teszi az első és a második paraméter egyenlőségének ellenőrzését. Azonnal vedd észre ez a módszer nem szigorú ellenőrzést végez, így csak skalárra alkalmas;
  • notEqual() az equal() ellentéte. Akkor kerül végrehajtásra, ha az első érték nem egyenlő a másodikkal;
  • strictEqual() - hasonlóan az equal()-hez egy különbséggel - szigorú ellenőrzést alkalmaz (azaz az adattípust is ellenőrzi);
  • notStrictEqual() - a strictEqual() ellentéte;
  • deepEqual() - metódus rekurzív utasításokhoz, primitívekhez, tömbökhöz, objektumokhoz használatos;
  • notDeepEqual() - a deepEqual() ellentéte;
  • A raises() egy állítás a kivételt dobó visszahívási függvények tesztelésére.

A második felsorolásban világosan megmutattam, hogyan kell ezeket a módszereket a gyakorlatban alkalmazni. Ha egy tesztesetet futtat ebben a formában, akkor minden teszt sikeres lesz (lásd a megfelelő ábrát). Annak érdekében, hogy lássam a különbséget a sikeres és a sikertelen tesztek között, kissé megváltoztattam az egyik teszt kódját. Szándékosan hibás eredményt adtam a teszt sorába a strictEqual() segítségével (lásd a megfelelő ábrát).

Lista 1. Az index.html fájl tartalma Tesztelés QUnittal



Egyszerű függvények tesztelésével érthetőnek tűnik. Mindenesetre nincs több hozzáfűznivalóm. Ezután elő kell vennie a valódi kódot, és meg kell próbálnia magának teszteket írni. Nézzünk egy másik gyakran előforduló feladatot a JavaScript-fejlesztők számára – az aszinkron függvények tesztelését. Egy JavaScript-kóddal megtöltött alkalmazás 99%-ban interakcióba lép a szerveroldallal az AJAX használatával. Ezt a kódot sem lehet tesztelés nélkül hagyni, de a tesztek írása egy kicsit másképp fog kinézni. Vegyünk egy példát:

AsyncTest("myAsyncFunc()", function () ( setTimeout(function () ( ok(myAsyncFunc() == true, "Az adatok sikeresen átmentek"); start(); ), 500; ));

A fő különbség e példa és az előző között az, hogy a test() burkoló helyett az asyncTest()-t használjuk, így közvetlenül jelzi, hogy érdekel az aszinkron tesztelés. Ezután elindítok egy 500 ezredmásodperces időtúllépést. Ezalatt a myAsyncFunc() függvénynek adatokat kell továbbítania a tesztszervernek, és ha minden rendben van, true értéket ad vissza. Itt jön a legérdekesebb pillanat. Az asyncTest() meghívásakor a végrehajtási szál leáll, és amikor a teszt befejeződött, magától el kell indítania. A végrehajtás folyamatának szabályozásához a QUnit biztosítja a start() és stop() metódusokat.


Az aszinkron funkciók tesztelése a QUnit könyvtárral meglehetősen egyszerű. Az utolsó példa, amelyet szeretnék megnézni, egy olyan teszt írása, amely több aszinkron ellenőrzést hajt végre. Az ilyen feladatok során felmerülő fő kérdés az, hogy mi az optimális hely a végrehajtási szál elindításához. A hivatalos doki valami ilyesmi használatát javasolja

AsyncTest("myAsyncFunc()", function () (vár ") ; ok(myAsyncFunc(), "A világ jobb hellyé tétele 3"); setTimeout(function () ( start(); ), 3000; ));

Egyéni műveletek tesztelése

Mindig emlékeznie kell arra, hogy sok mindenféle interfész dolog JavaScriptben van írva. Például egy felhasználó rákattint egy stricire, és valaminek történnie kell a kattintására válaszul. Hatalmas mennyiségű ilyen „interfész” kód található a projektekben, és azt is le kell fedni tesztekkel. Nézzük meg, hogyan szimulálhatunk felhasználói billentyűleütést, és írjunk külön tesztet ehhez a művelethez. Képzeljük el, hogy van valami funkciónk, amely naplózza a lenyomott billentyűket. A harmadik listában megadtam neki a kódot.

Lista 3. Billentyűleütések naplózása funkció KeyLogger(target) ( if (!(ez a KeyLogger példány)) ( return new KeyLogger(target); ) this.target = target; this.log = ; var self = this; this.target. off ("keydown").on("keydown", function(event) ( self.log.push(event.keyCode); )); )

Most próbáljuk meg ezt a funkciót tesztelni. Először is, a teszt törzsében emulálni kell a lenyomott billentyűt. Ennek legegyszerűbb módja a jQuery könyvtár, amely lehetővé teszi egy esemény létrehozását néhány kódsorból (lásd a 4. listát).

Lista 4. Tesztkód a KeyLogger teszthez("Kulcs rögzítési teszt", függvény () ( var event, $doc = $(document), keys = KeyLogger($doc); event = $.Event("keydown"); esemény .keyCode = 9; $doc.trigger(event); equal(keys.log.length, 1, "Key logged"); equal(keys.log, 9, "A gomb lenyomva a 9-es kóddal"); ));

A listázás legelején a teszttel előkészítek egy eseményt a billentyűleütés emulálására - "keydown". Kíváncsiak leszünk a Tab billentyű lenyomására (9-es kód). Ezután a trigger() metódussal elküldöm az előkészített eseményt, ami után kezdhetem a tesztelést. Először ellenőrizzük az összképet - hogy megnyomtak-e egy billentyűt, majd a kódját.

DOM tesztek leple alatt

Mivel a Quinit.js lehetővé teszi az egyéni műveletek tesztelését, a DOM tesztek írása sem jelenthet problémát. Ez igaz, és az alábbi példa megerősíti szavaimat. Nem kommentálom, csak vessen egy pillantást a kódra, és minden világossá válik:

Test("Új div elem hozzáadása", függvény () ( var $fixture = $("#qunit-fixture"); $fixture.append("

Ez az új div
"); equal($("div", $fixture).length, 1, "Új div sikeresen hozzáadva!"); ));

PhantomJS - tesztek futtatása a konzolról


A QUnit.js könyvtár használatával teszteket írni kényelmes és egyszerű, de előbb-utóbb meglátogatja a vágy, hogy valahogy automatizálja az indítást, a tesztelést és az eredmények gyűjtését. Például ehhez a vállalkozáshoz van egy külön virtuális gépem a DigitalOceanben, amit csak a konzol segítségével tudok kezelni.

A PhantomJS projekt elég elegánsan oldja meg ezt a problémát. Ez nem csak egy újabb keretrendszer az egységtesztek írására, hanem a WebKit motor teljes értékű konzolváltozata. Egyszerűen fogalmazva, ez az alkalmazás egy böngészőt emulál. A PhantomJS segítségével valóban nem csak a tesztvégrehajtás ellenőrzésének automatizálásáról van szó, hanem egy csomó olyan feladat megoldásáról is, amelyek előbb-utóbb a fejlesztők előtt felmerülnek: az oldalak renderelési eredményeinek fájlba kerülése (PNG, JPG), hálózatfigyelő funkciók (betöltési sebesség, általános teljesítmény stb.), felhasználói műveletek emulálása és így tovább. Azt javaslom, hogy ne legyen lusta, és olvassa el a projekt hivatalos dokumentációját, biztosan talál valami érdekeset magának.

A PhantomJS különböző platformokra fordítható (*nix, OS X, Windows). Ha mindent Windows alatt fejleszt, akkor nincs probléma - egyesítse a binárisokat, és folytassa. Kisebb nehézségek adódhatnak az indítással, ha két videoadapter van telepítve, amelyek közül az egyik az NVIDIA. Ebben az esetben az oldalsávban leírt feltörést kell használnia.


Próbáljunk meg a gyakorlatban is megismerkedni a PhantomJS-sel. Az utolsó szakaszban elkészített tesztek PhantomJS-en keresztüli futtatásához és a végrehajtás eredményeinek a konzolon való lekéréséhez szükségünk van egy speciális betöltő szkriptre - run-qunit.js . Nyissa meg a konzolt (Windows alatt dolgozom, ezért cmd-t használok), és írja be a parancsot a formátumban

phantom.exe<путь к run-qunit.js> <путь к странице с тестами>

Az én esetemben az indítási parancs így alakult:

E:\soft\phantomjs>phantomjs.exe E:\temp\testjsforx\qunit\run-qunit.js file:///E: /temp/testjsforx/qunit/index.html

A végrehajtás eredménye:

A tesztek 2592 ezredmásodperc alatt fejeződtek be. 9 állítás 9-ből sikeres, 0 nem sikerült.

Minden teszt sikeres

A kódot mindenképpen le kell fedni tesztekkel, és nem mindegy, milyen léptékben készítjük az alkalmazást. Még egyszer emlékeztetlek: a legkisebb programok is esetlen szörnyetegekké válnak, amelyeket támogatni és funkcionalitással kell kiegészíteni. A jól tesztelt kód a siker és a minőség kulcsa. Igen, nem könnyű azonnal elkezdeni az automatizált tesztekre alkalmas kódot írni, de higgyétek el, ez a sok kínlódás a jövőben kifizetődik. Mára ennyi, sok sikert!

PhantomJS problémák Windows rendszeren

Így történt, de a cikkben szereplő összes példát nem Linuxon teszteltem, hanem a jó öreg Windows 7 alatt. Kiderült, hogy a PhantomJS-nek vannak problémái, amikor több videoadaptert használó rendszereken dolgozik. A laptopomon az integrált videochip mellett az NVIDIA is kilóg, és emiatt a PhantomJS kategorikusan nem volt hajlandó reagálni a phantom.exit () parancsra. Ennek eredményeként a szkript végrehajtása után a PhantomJS folyamat nem fejezte be a munkáját, és továbbra is lógott a memóriában. A terminálablak szintén nem reagál a kilépési parancsokra ( nem segített).

Ha hasonló problémával szembesül, és a PhantomJS használatát tervezi Windows rendszeren, akkor készüljön fel a következő feltörésre. nyitott panel NVIDIA vezérlés. Keresse meg a „3D beállítások” elemet a fában. A jobb oldalon a „Preferált grafikus adapter". Alapértelmezés szerint. értéke Autoselect-re van állítva. Módosítanunk kell "High Performance NVIDIA Processor" vagy "Integrated Graphics Hardware"-re. Ezen egyszerű trükk után a PhantomJS engedelmesen kezdett viselkedni.

A hatékony tesztesetek létrehozása kritikus lehet nagy projektek, ha az alkalmazás egyes részeinek viselkedése különböző okok miatt megváltozhat. Talán a leggyakoribb probléma az, amikor fejlesztők nagy csoportja dolgozik ugyanazon vagy kapcsolódó modulokon. Ez nem tervezett változáshoz vezethet más programozók által írt függvények viselkedésében. Vagy a szoros határidők betartása az alkalmazás kritikus részeinek véletlen megváltoztatásához vezet.

A webalkalmazás tesztelése általában az oldalelemek vizuális értékeléséből és a funkcionalitás teljesítményének empirikus értékeléséből áll. Más szóval a szakaszok közötti navigálásban és a dinamikus elemeken végzett műveletekben.

Idővel a projekt megtelik újakkal funkcionalitás, ami meghosszabbítja és megnehezíti a munkája ellenőrzésének folyamatát. Az automatizáláshoz az egységtesztet használják.

Kétféle megközelítés létezik a tesztforgatókönyvek létrehozására:

  • fehér doboztesztelés– a tesztek írása a funkcionalitás megvalósításán alapul. Azok. ugyanazokat az algoritmusokat vizsgáljuk, amelyeken rendszerünk moduljainak munkája alapul. Ez a megközelítés nem garantálja a rendszer egészének megfelelő működését.
  • fekete doboztesztelés– A szkriptelés a specifikációkon és a rendszerkövetelményeken alapul. Így ellenőrizheti a teljes alkalmazás eredményeinek helyességét, de ez a megközelítés nem teszi lehetővé az apró és ritka hibák elkapását.

Mit kell tesztelni

Jó ötletnek tűnhet minden beépített funkció tesztelése. Ez nem teljesen igaz. A tesztek megírása a fejlesztőtől időt vesz igénybe, ezért az alkalmazáskészítés folyamatának optimalizálása érdekében csak az összetett, kritikus, vagy más rendszermodulok eredményétől függő funkciókra érdemes teszteket készíteni. Fedje le a teszteket kétértelmű logikával, amelyek potenciálisan hibákat tartalmazhatnak. A jövőben optimalizálni tervezett kódrészekhez is érdemes teszteket készíteni, hogy az optimalizálás után megbizonyosodhass azok helyes végrehajtásáról.

Általánosságban elmondható, hogy rendkívül fontos a tesztelés költségeinek értékelése a fejlesztési idő szűkösségéhez képest. Természetesen, ha nincs időkorlát, minden funkciót tesztelhet. De a fejlesztés általában szűkös időkényszerben történik, így egy elemző vagy egy tapasztalt fejlesztő feladata, hogy megértse, hol van szükség tesztelésre. Ráadásul a tesztek írása megnöveli a projekt költségeit.

Így 3 esetet tudunk megfogalmazni, amikor az egységteszt alkalmazása indokolt:

1) Ha a tesztek lehetővé teszik a hibák gyorsabb azonosítását, mint a szokásos kereséssel.

2) Csökkentse a hibakeresési időt

3) Lehetővé teszi a gyakran változó kód tesztelését.

A frontend 3 fő összetevője közül (HTML, CSS, JavaScript) talán csak a JavaScript kódot kell tesztelni. A CSS-t csak vizuálisan ellenőrzik, amikor a fejlesztő/tesztelő/ügyfél megtekinti GUI különböző böngészőkben. HTML - a jelölés ellenőrzése ugyanezzel a módszerrel történik.

Hogyan kell tesztelni

A tesztforgatókönyvek kialakításakor a következő elveket kell követnie:

  • A teszteknek a lehető legegyszerűbbeknek kell lenniük. Akkor valószínűbb, hogy az ismételni kívánt hiba hatással lesz a megvalósítás eredményeire.
  • Nagy modulok tesztjeinek felbontása. Grove segítségével keresse meg a hiba konkrét helyét.
  • Tedd függetlenné a teszteket. Az egyik teszt eredménye semmi esetre sem függhet a másik eredményétől.
  • A vizsgálati eredményeknek teljesen megismételhetőnek és várhatónak kell lenniük. Minden alkalommal, amikor újra futtatja a tesztet, az eredménynek ugyanaznak kell lennie, mint az előző alkalommal.
  • Bármilyen hiba esetén az alkalmazás végrehajtása során tesztszkriptet kell készíteni.Így biztos lehet benne, hogy a hiba valóban javítva van, és nem jelenik meg a felhasználók számára.

Hogyan kell tesztelni

Számos könyvtár létezik a js kód egység tesztelésére. Talán a leggyakoribb a QUnit. Ahhoz, hogy egységteszteket végezhessünk ezzel a könyvtárral, létre kell hoznunk egy "homokozót" - egy egyszerű html oldalt, amelyhez a tesztelő könyvtár, a tesztelendő kód és maguk a tesztek csatlakoznak.

A tesztek funkciói:

(function() ( window.stepen = function(int) ( var result = 2; for (var i = 1; i< int; i ++) { result = result * 2; } return result; } window.returnFunc = function() { return "ok"; } })();

Tesztlista:

Test("stepen()", function() ( egyenlő(stepen(2), 4, "2^2 - egyenlő metódus"); ok(stepen(3) === 8, "2^3 - ok metódus") ); deepEqual(stepen(5), 32, "2^5 - deepEqual metódus"); )); asyncTest("returnFunc()", function() ( setTimeout(function() ( egyenlő(returnFunc(), "ok", "Async Func Test"); start(); ), 1000; ));

Mint látható, a QUnit 3 funkciót támogat a kódvégrehajtás eredményeinek a várttal való összehasonlítására:

  • rendben()- sikeresnek tekinti a tesztet, ha a visszatérési eredmény igaz
  • egyenlő()- összehasonlítja az eredményt a várttal
  • deepEqual()- összehasonlítja az eredményt a várttal, ellenőrizve annak típusát

A végrehajtás eredménye:

Mint látható, a QUnit könyvtár egyszerre több böngésző kódját is teszteli.

Számos más könyvtár is létezik az egységtesztekhez. A tesztszkriptek felépítésének koncepciója azonban megegyezik bennük, így az egyikkel foglalkozva nem lesz nehéz másikra váltani.

Fontos megjegyezni

A modern js kód egyik jellemzője a végrehajtás aszinkronitása. A tesztelésre szolgáló könyvtárak általában képesek aszinkron tesztek elvégzésére. De például, ha olyan függvényt próbálunk tesztelni, amely mondjuk get kérést küld a háttérnek és választ ad vissza onnan, akkor a tesztek elvégzéséhez le kell állítani a szálat a stop() függvénnyel, a tesztelés alatt álló függvényt, majd indítsa újra a szálat a start() metódussal, "csomagolva" a setTimeout()-ba. Azok. be kell állítani egy bizonyos időintervallumot, amely alatt a funkció végrehajtásának be kell fejeződnie. Gondosan meg kell választani ennek a szakasznak az időtartamát, .k. egyrészt a módszer hosszadalmas munkája lehet az alkalmazási funkcionalitás egy konkrét megvalósításának jellemzője, vagy akár szükségszerűsége, vagy helytelen viselkedés.

A gerinchálózati alkalmazások tesztelése

A Backbone.js használatával írt alkalmazások tesztelésének példájához a -ban leírt projektet fogjuk használni.

Egységtesztekkel ellenőrizheti:

  • A modellek és vezérlők létrehozásának helyessége
  • Az adatok helyessége a modellekben
  • Vezérlő metódusok végrehajtása (ehhez eredményt kell visszaadniuk)
  • Sikeres betöltés megtekintése

Teszt kód:

Test("Backbone.js", function() ( ok(minta, "Namespace check"); ok(sample.routers.app, "Router check"); ok(sample.core.pageManager.open("chat") , "Oldalnyitó teszt (Controller metódushívás)") ok(sample.core.state, "Model check"); equal(sample.core.state.get("content"), "sintel", "Model data get test "); stop(); ok(function() ( $.ajax(( url: "app/templates/about.tpl", dataType: "text" )).done(function(data) ( self.$el. html(data); return data; )) ), "Sablonbetöltési ellenőrzés"); setTimeout(function() ( start(); ), 1000; ));

A tesztelési hibákkal végzett munka eredménye:

Próbaüzem automatizálása

Általában egy alkalmazás üzembe helyezése olyan feladat, amelyet az intenzív fejlesztés során gyakran kell elvégezni. Ezért ez a művelet általában automatizált. Munkánk során a Jenkinst, a folyamatos integrációs eszközt használjuk. Az ötlet az, hogy a Jenkins-en keresztüli telepítést automatizált tesztekkel kombinálják.

A QUnit tesztek a böngészőben futnak. A Phantomjs, a böngészőt emuláló szoftver segít megkerülni ezt a funkciót. A phantomjs fejlesztői már biztosítottak egy szkriptet a QUnit tesztek végrehajtásához, de a megfelelő működéshez kissé módosítani kellett.

/** * Várjon, amíg a tesztfeltétel igaz, vagy időtúllépés következik be. * Hasznos a szerver válaszára * vagy a felhasználói felület megváltoztatásához (fadeIn stb.) való várakozáshoz. * * @param testFx javascript feltétel, amely logikai értékre kiértékelődik, * karakterláncként adható át (pl.: "1 == 1" vagy * "$("#bar").is(":visible")" vagy * visszahívási függvényként. * @param onKészen áll, mit kell tenni, ha a testFx feltétel teljesül, * átadható karakterláncként (pl.: "1 == 1" vagy * "$("#bar").is (":visible")" vagy * visszahívási függvényként. * @param timeOutMillis a várakozási idő maximális időtartama. Ha * nincs megadva, akkor 3 mp használatos. */ function waitFor(testFx, onReady, timeOutMillis) ( var maxtimeOutMillis = timeOutMillis - timeOutMillis: 3001, //< Default Max Timout is 3s start = new Date().getTime(), condition = false, interval = setInterval(function() { if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) { // If not time-out yet and condition not yet fulfilled condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code } else { if(!condition) { // If condition still not fulfilled // (timeout but condition is "false") console.log(""waitFor()" timeout"); phantom.exit(1); } else { // Condition fulfilled (timeout and/or condition is //"true") console.log(""waitFor()" finished in " + (new Date().getTime() - start) + "ms."); typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it"s supposed to do once the // condition is fulfilled clearInterval(interval); //< Stop this interval } } }, 100); // repeat check every 250ms }; }; if (phantom.args.length === 0 || phantom.args.length >2) console.log("Használat: run-qunit.js URL"); phantom.exit(); ) var page = new WebPage(); // A "console.log()" hívások átirányítása az oldal // kontextusból a fő fantom kontextusba (vagyis az aktuális "this") page.onConsoleMessage = function(msg) ( console.log(msg); ); page.open(phantom.args, function(status)( if (status !== "siker") ( console.log("Nem lehet elérni a hálózatot"); phantom.exit(); ) else ( waitFor(function() ( return page.evaluate(function()( var el = document.getElementById("qunit-testresult"); if (el && el.innerText.match("befejezve")) ( return true; ) return false; )); ), function()( var failedNum = page.evaluate(function()( var el = document.getElementById("qunit-testresult"); console.log(el.innerText); try ( return document.getElementsByClassName("sikertelen") ).innerHTML.length; ) catch (e) ( return 0; ) return 10000; )); phantom.exit((parseInt(failedNum, 10) > 0) ? 1: 0; )); ) ));

Az eredményüzenetek konzolon való megjelenítéséhez hozzá kell adni a naplózási funkciót a tesztszkripthez.

Az oldal most tesztelhető a következő témák ismeretében: HTML, css, JavaScript, PHP, SQL.

Minden teszt a következőkből áll 10 kérdések egy adott témában. Minden kérdésben igyekeztem egy-egy nyelv legkülönfélébb alkalmazási területeit érinteni, hogy tudásszintjét minél alaposabban ellenőrizhessem.

Természetesen mindent a tesztek ingyenesekés bárki átmehet.

Vizsgálati eljárás:

  1. Kövesd a linket" Kezdje el a tesztelést" a megfelelő tesztből.
  2. Válaszoljon a kérdésekre a választással az egyetlen helyes opció.
  3. A tesztelés végeztével látni fogod pontszámod, hibák száma, és az egyes kérdések elemzése a tesztből.

Figyelem! Az előző kérdésre való visszatérés nem fog működni, ezért mielőtt válaszolna, gondolkozzon.

Jelenleg elérhető tesztek

  1. HTML

    • Összes teljesített teszt: 75424 fő
    • Átlagpontszám: 2,83 az 5-ből pontokat.

    Alapismereti teszt HTML. Tudnia kell az alapokat HTML címkékés megfelelő használatukat. Meg kell érteni a szabvány jellemzőit is XHTML 1.1.

  2. css

    • Összes teljesített teszt: 32828 ember
    • Átlagpontszám: 3,37 az 5-ből pontokat.

    A teszt az alapismeretek ismeretét teszi próbára css. A teszt sikeres teljesítéséhez ismernie kell a szelektorok alaptípusait (szintaxisát), ismernie kell az alapvető tulajdonságokat és azok lehetséges értékeit, valamint ismernie kell a legnépszerűbb pszeudoelemek célját is.

  3. JavaScript

    • Összes teljesített teszt: 24845 fő
    • Átlagpontszám: 3,31 az 5-ből pontokat.

    Ez a kvíz teszteli a JavaScript nyelv ismereteit. A teszt kérdései különböző alkalmazási területeket fednek le adott nyelv. Sok kérdés merül fel az "apró" árnyalatok megértésével kapcsolatban. Ellenkező esetben alapvető dolgokat kell tudnia: változókkal való munka, alapvető JavaScript-függvények, operátori prioritások stb.

  4. PHP

    • Összes teljesített teszt: 33239 fő
    • Átlagpontszám: 3,03 az 5-ből pontokat.

    Ez a kvíz teszteli a PHP nyelv tudását. Ismernie kell az alapvető PHP konstrukciókat, dolgoznia kell változókkal, szekciókkal, átirányítási implementációval és egyéb szabványos dolgokkal.
    Meggyőző kérés: A teszt sok kérdést tartalmaz, például: "Mit fog kiadni a szkript?". Nagy kérés, ne másolja le és ellenőrizze. Légy őszinte magadhoz.

  5. SQL

    • Összes teljesített teszt: 18014 fő
    • Átlagpontszám: 3,28 az 5-ből pontokat.

    Ez a teszt teszteli a nyelvtudását SQL lekérdezések. A kérdések csak ennek a nyelvnek a legalapvetőbb ismereteit fedik le, minden elmélyülés nélkül. Szüksége lesz a legalapvetőbb SQL-lekérdezések ismeretére, valamint azok kompetens használatára.

Egy egyszerű számológép példáján a Node.js-en. A Mocha keretrendszerrel teszteljük.

Amire az alkalmazásunknak képesnek kell lennie:

  • Tetszőleges két szám összeadása, kivonása, osztása és szorzása;
  • Figyelmeztetés megjelenítése és kilépés, ha számon kívül mást is beírtak;
  • Egy parancssori felületnek is kell lennie, hogy a végfelhasználó használni tudja az alkalmazást.

Amire szükségünk van:

  • Node.js és npm
  • JavaScript ismerete: szintaxis és kódstruktúra, adattípusok, matematikai műveletek és feltételes kifejezések.

A kitűzött célok után elkezdheti felállítani a tesztelési és fejlesztési környezetet.

A környezet kialakítása

Mivel Node.js-t használunk, létre kell hoznunk egy helyi környezetet a fájlok és függőségek számára.

Teremt új mappa kalc. A parancssorban váltson át erre a könyvtárra, és hozzon létre egy új projektet az npm init segítségével, amely létrejön új fájl package.json programunkhoz.

A rendszer kéri, hogy adja meg a csomag nevét, verzióját, leírását és a csomagra vonatkozó egyéb információkat. Megadhat egy nevet calc.jsés nyomd tovább Belép alapértelmezett értékek hozzárendeléséhez. Amikor eléri a test parancsot, írja be, hogy mocha – ez a tesztelési keretrendszer, amelyet használni fogunk:

tesztparancs: mokka

Az összes információ megadása után a szkript létrehoz egy fájlt package.json, ami valahogy így néz ki:

( "name": "calc.js", "verzió": "1.0.0", "description": "Egyszerű számológép a Node.js-ben", "main": "index.js", "scripts": ( " teszt": "mokka" ), "szerző": "", "licenc": "ISC" )

A lépés utolsó lépése a Mocha telepítése. A telepítéshez írja be a következő parancsot:

npm install --save-dev mokka

A parancs alkalmazása után megjelenik egy mappa node_modules, fájl package-lock.json, és a fájlban package.json a következő sorok jelennek meg:

"devDependencies": ( "mocha": "^4.0.1" )

Hozzon létre egy fájlt test.js. A Node.js beépített modulját fogjuk használni állítja ellenőrizni, hogy igaz és igaz igaz-e. Mivel ez igaz, a tesztnek sikeresnek kell lennie:

Const assert = request("assert"); it("igazt kell visszaadnia", () => ( assert.equal(igaz, igaz; ));

Most futtassa a tesztet a parancssorból:

$ npm teszt > mokka ✓ igaz 1-et kell visszaadnia (8 ms)

A teszt a vártnak megfelelően ment, így a környezet beállítása megtörtént. Eltávolitani a test.js minden, kivéve a sort const assert = request("assert"); .

A fájlt fogjuk használni test.js az alkalmazásfejlesztési folyamat során. Hozzon létre még két fájlt: Operations.js aritmetikai és érvényesítési függvényekhez és calc.js magának az alkalmazásnak. Annyi fájlt használunk, hogy nem lesznek túl hosszúak és bonyolultak. Íme az aktuális fájllistánk:

  • calc.js;
  • node_modules;
  • Operations.js;
  • package-lock.json;
  • package.json;
  • test.js;

Adjuk hozzá az elsőt igazi teszt pályázatunkhoz.

Matematikai műveletek hozzáadása

Először is, az alkalmazásunknak képesnek kell lennie bármely két szám összeadására, kivonására, osztására és szorzására. Tehát minden egyes művelethez külön függvényt kell létrehoznunk.

Kezdjük a kiegészítéssel. Írunk egy tesztet, amely egyedileg megkapja két szám várt összegét. Az alábbi kódban az add() 4 függvény segítségével ellenőrizzük, hogy 1 és 3 összege egyenlő-e:

Const assert = request("assert"); it("helyesen megtalálja 1 és 3 összegét", () => ( assert.equal(add(1, 3), 4; ));

Az npm teszt paranccsal végzett teszt futtatása után a következőket látjuk:

> mokka 0 átmegy (9ms) 1 sikertelen 1) helyesen találja meg az 1 és a 3 összegét: ReferenceError: az add nincs megadva a Context.it-ben (test.js:5:16) npm ERR! teszt sikertelen. További részletekért lásd fent.

A teszt ReferenceError hiba miatt meghiúsult: az add nincs megadva. Teszteljük az add() függvényt, ami még nem létezik, így ez az eredmény eléggé várható.

Hozzunk létre egy add() függvényt egy fájlban Operations.js:

Const add = (x, y) => (+x) + (+y);

Ez a függvény két x és y argumentumot vesz fel, és ezek összegét adja vissza. Talán észrevetted, hogy x + y helyett (+x) + (+y)-t írunk. Az unáris operátort használjuk arra, hogy az argumentumot egy számra öntsük, ha a bemenet egy karakterlánc.

Megjegyzés Ez egy ES6-hoz hozzáadott nyílfüggvényt és implicit visszatérést használ.

Mivel a Node.js-t használjuk, és a kódot több fájlra osztjuk, a module.exports fájlt kell használnunk a kód exportálásához:

Const add = (x, y) => (+x) + (+y); module.exports = ( hozzáadás )

A fájl elején test.js kódot importálunk Operations.js a request() -vel. Mivel a függvényt a műveleti változón keresztül használjuk, az add()-t módosítanunk kell az operations.add() -ra:

Const műveletek = követelmény("./operations.js"); const assert = request("assert"); it("helyesen megtalálja 1 és 3 összegét", () => ( assert.equal(operations.add(1, 3), 4; ));

Futtassuk le a tesztet:

$ npm teszt > mokka ✓ helyesen találja meg az 1 és 3 1 összegét, amely megfelel (8 ms)

Most már működő funkciónk van, és a tesztek sikeresen teljesítenek. Mivel a többi művelet függvényei hasonló módon működnek, a kivonás() , szorzás() és osztó() tesztek hozzáadása egyszerű:

It("helyesen megtalálja 1 és 3 összegét", () => ( assert.equal(operations.add(1, 3), 4; )); it("helyesen megtalálja a -1 és -1 összegét", () => ( assert.equal(operations.add(-1, -1), -2; )); it("helyesen megtalálja a különbséget 33 és 3 között", () => ( assert.equal(operations.subtract(33, 3), 30; )); it("helyesen megtalálja 12 és 12 szorzatát", () => ( assert.equal(operations.multiply(12, 12), 144; )); it("helyesen megtalálja 10 és 2 hányadosát", () => ( assert.equal(operations.divide(10, 2), 5; ));

Most hozzuk létre és exportáljuk az összes függvényt ide test.js:

Const add = (x, y) => (+x) + (+y); const kivonás = (x, y) => (+x) - (+y); const szorzás = (x, y) => (+x) * (+y); const oszt = (x, y) => (+x) / (+y); module.exports = ( összeadás, kivonás, szorzás, osztás, )

És futtass új teszteket:

$ npm teszt > mokka ✓ helyesen találja meg 1 és 3 összegét ✓ helyesen találja meg -1 és -1 összegét ✓ helyesen találja meg a 33 és 3 közötti különbséget ✓ helyesen találja meg 12 és 12 szorzatát ✓ helyesen találja meg 10 hányadosát és 25 múlik (8 ms)

Minden teszt sikeresen lezajlott, így most már biztosak lehetünk abban, hogy alkalmazásunk fő funkciói megfelelően fognak működni. Most további ellenőrzéseket végezhetünk.

Érvényesítés hozzáadása

Abban a pillanatban, amikor a felhasználó beír egy számot, és kiválasztja a kívánt műveletet, minden jól működik. De mi történik, ha megpróbáljuk megtalálni egy szám és egy karakterlánc összegét? Az alkalmazás megpróbálja végrehajtani a műveletet, de mivel számot vár, NaN -t ad vissza.

Ahelyett, hogy néhány furcsa értéket adna vissza, itt az ideje a második feladat elvégzésére - az alkalmazás figyelmeztetés megjelenítésére és kilépésre, ha a bemeneti argumentum nem szám.

Először meg kell írnia egy függvényt, amely ellenőrzi, hogy a bemenet szám-e vagy sem. Az alkalmazásnak csak számokkal kell működnie, ezért három helyzetet fogunk kezelni:

  1. Mindkét bemenet szám.
  2. Az egyik bemenet egy szám, a másik pedig egy karakterlánc.
  3. Mindkét bemenet karakterlánc.
it("hibát jelent, ha egy karakterláncot használ szám helyett", () => ( assert.equal(operations.validateNumbers("sammy", 5), false); )); it("hibát jelent, ha két karakterláncot használ számok helyett", () => ( assert.equal(operations.validateNumbers("sammy", "sammy"), false; )); it("siker két szám használatakor", () => ( assert.equal(operations.validateNumbers(5, 5), true); ));

A validateNumbers() függvény mindkét paramétert érvényesíteni fogja. Az isNaN() függvény ellenőrzi, hogy a paraméter nem szám-e, és ha nem, akkor false értéket ad vissza. Ellenkező esetben true értéket ad vissza, ami sikeres érvényesítést jelent.

Const validteNumbers = (x, y) => ( if (isNaN(x) && isNaN(y)) ( return false; ) visszatér igaz; )

Ne felejtse el hozzáadni a validateNumbers-t a module.exports fájlhoz a fájl végén. Most új teszteket futtathat:

$ npm teszt 1) hibát jelez, ha egy karakterláncot használ szám helyett ✓ hibát jelez, ha két karakterláncot használ számok helyett ✓ sikeres, ha két számot használ 7 sikeres (12 ms) 1 sikertelen 1) hibát jelent, ha karakterláncot használ helyette számból: AssertionError : igaz == hamis + várható - tényleges -igaz + hamis

Két teszt sikeres volt, de egy nem sikerült. A két szám tesztje sikeres volt, akárcsak a két húr tesztje. Mi nem mondható el a karakterlánc és egy szám bemenetének ellenőrzéséről.

Ha újra megnézzük a funkciónkat, ezt láthatjuk mindkét A paramétereknek NaN-nek kell lenniük ahhoz, hogy a függvény false értéket adjon vissza. Ha ugyanazt a hatást szeretnénk elérni, ha legalább az egyik paraméter NaN , akkor az && helyett || :

Const validteNumbers = (x, y) => ( if (isNaN(x) || isNaN(y)) ( hamis visszatér; ) igazat ad vissza; )

Ha a módosítások után újra futtatja az npm tesztet, akkor minden teszt sikeres lesz:

✓ hibát jelez, ha egy karakterláncot használ szám helyett ✓ hibát jelez, ha két karakterláncot használ számok helyett ✓ sikert, ha két számot használ 8 áthalad (9 ms)

Alkalmazásunk összes funkcióját teszteltük. A függvények sikeresen végrehajtják a matematikai műveleteket és érvényesítik a bemenetet. Az utolsó szakasz a felhasználói felület létrehozása.

Interfész létrehozása

A szükséges funkciókkal már rendelkezünk, de a felhasználó továbbra sem tudja azokat semmilyen módon használni. Tehát szükségünk van egy interfészre. Alkalmazásunkhoz létrehozunk egy parancssori felületet.

Jelenleg a fájl calc.jsüresnek kell lennie. Ez az a hely, ahol az alkalmazásunk tárolódik. Először is importálnia kell a függvényeket innen Operations.js:

Const műveletek = követelmény("./operations.js");

Maga az interfész a Node.js beépített Readline CLI modulját fogja használni:

Const readline = request("readline");

Miután importált mindent, amire szüksége van, megkezdheti az alkalmazás létrehozását. A felület létrehozásához a readline -t használjuk, amely az rl változón keresztül érhető el:

Const rl = readline.createInterface(( bemenet: process.stdin, kimenet: process.stdout ));

Az első dolog, amit a felhasználónak látnia kell a program elindítása után, egy üdvözlő üzenet és a használati utasítás. Ehhez a console.log() függvényt használjuk:

Console.log(` Calc.js Megnyitott egy Node.js számológépet! Verzió: 1.0.0. Használat: a felhasználónak be kell írnia két számot, majd ki kell választania, hogy mit kezdjen velük. `);

Mielőtt magukkal a számológép-függvényekkel foglalkoznánk, ellenőrizzük, hogy a console.log() megfelelően működik-e. A programot kinyomtatjuk és kilépünk. Ehhez adjunk hozzá egy hívást az rl.close() metódushoz a végén.

Az alkalmazás futtatásához írja be a node-ot, majd egy fájlnevet:

$ node calc.js Calc.js Megnyitotta a Node.js számológépet! Verzió: 1.0.0. Használat: A felhasználónak be kell írnia két számot, majd ki kell választania, hogy mit kezdjen velük.

A program üdvözlő üzenetet jelenít meg, és kilép. Most felhasználói bevitelt kell hozzáadnunk. A felhasználónak két számot és egy műveletet kell kiválasztania. Minden bemenetet az rl.question() metódus kér:

Rl.question("Írja be az első számot: ", (x) => ( rl.question("Írja be a második számot: ", (y) => ( rl.question(`) Válasszon egyet a következő műveletek közül: Add ( +) Kivonás (-) Szorzás (*) Osztás (/) Az Ön választása: `, (choice) => ( // itt további kód jelenik meg rl.close(); )); )); ));

Az x változóhoz van rendelve az első szám, y a másodikhoz, és a választás a kiválasztott művelet. Most a programunk kér bevitelt, de nem csinál semmit a kapott adatokkal.

A harmadik bevitel után ellenőriznie kell, hogy csak számokat írt-e be. Ehhez a validateNumbers() függvényt fogjuk használni. A NOT operátor segítségével ellenőrizzük, hogy beírták-e a számokat, és ha nem, akkor kilépünk a programból:

If (!operations.validateNumbers(x, y)) ( console.log("Csak számok megengedettek! Kérjük, indítsa újra a programot."); )

Ha mindent helyesen adott meg, most le kell futtatnia a korábban létrehozott megfelelő műveleti módszert. A négy lehetséges választás feldolgozásához egy switch utasítást használunk, és kiadjuk a művelet eredményét. Ha nem létező műveletet választott ki, akkor az alapértelmezett blokk kerül végrehajtásra, és felszólítja a felhasználót, hogy próbálkozzon újra:

If (!operations.validateNumbers(x, y)) ( console.log("Csak számokat lehet megadni! Kérjük, indítsa újra a programot."); ) else ( switch (choice) ( "1" eset: console.log(` $(x) és $(y) összege: $(operations.add(x, y)).`); break; "2" eset: console.log(`$(x) és $(y) különbsége egyenlő $( operations.subtract(x, y)).`); break; "3" eset: console.log(`$(x) és $(y) szorzata: $(operations.multiply(x, y) ).`) ; break; "4" kisbetű: console.log(`Private $(x) és $(y) egyenlő: $(operations.divide(x, y)).`); break; alapértelmezett: console.log ("Kérjük, indítsa újra a programot, és válasszon egy számot 1 és 4 között."); szünet; ) )

Megjegyzés: Az itt található console.log() függvények olyan sablonkarakterláncokat használnak, amelyek lehetővé teszik a kifejezéseket.

/** * Egy egyszerű Node.js számológép, amely a beépített Readline parancssori felületet * használó számológép alkalmazást használja. */ const műveletek = igény("./operations.js"); const readline = request("readline"); // A readline használatával interfész hozzon létre const rl = readline.createInterface(( input: process.stdin, output: process.stdout )); console.log(` Calc.js Megnyitott egy Node.js számológépet! Verzió: 1.0.0. Használat: A felhasználónak be kell írnia két számot, majd ki kell választania, hogy mit kezdjen velük. `); rl.question("Írja be az első számot: ", (x) => ( rl.question("Írja be a második számot: ", (y) => ( rl.question(` Válasszon egyet a következő műveletek közül: Add () +) Kivonás (-) Szorzás (*) Osztás (/) Az Ön választása: `, (choice) => ( if (!operations.validateNumbers(x, y)) ( console.log("Csak számokat írhat be! Kérem indítsa újra a programot. "); ) else ( switch (choice) ("1" eset: console.log(`A $(x) és $(y) összege egyenlő: $(operations.add(x, y)). `); break; kis- és nagybetű "2": console.log(`A $(x) és $(y) közötti különbség: $(operations.subtract(x, y)).`; break; kis- és nagybetű "3": console.log(`A $( x) és $(y) szorzata: $(operations.multiply(x, y)).`; break; "4" kisbetű: console.log(`Private $(x) és $(y) egyenlő: $(operations. divide(x, y)).`); break; default: console.log("Kérjük, indítsa újra a programot, és válasszon egy számot 1 és 4 között."); break; ) ) rl.close(); )); )) ; ));

Most már elkészült az alkalmazásunk. A végén nézzük meg a munkáját. Írja be a 999-et és az 1-et, és válassza ki a kivonási műveletet:

$ node calc.js Írja be az első számot: 999 Írja be a második számot: 1 Az Ön választása: 2 A 999 és az 1 közötti különbség 998.

A program sikeresen befejezte munkáját, a megfelelő eredményt megjelenítve. Gratulálunk, írt egy egyszerű számológépet a Node.js használatával, és megtanulta a TDD fejlesztés alapjait.



Betöltés...
Top