Kiknek szól ez a cikk?
A potenciális megrendelőknek és kicsit a fejlesztőknek. A megrendelőknek segít abban, hogy egyáltalán hogyan érdemes vélekedni a Unit tesztről. Mi ez, mire való, mennyi idő és mit ér? A fejlesztőknek pedig egy fajta könnyű olvasmány, amivel vagy egyet tudnak érteni, vagy nem.
Olvastam a napokban egy hirdetést, amelyben egy Senior fejlesztő úgy hirdette magát, hogy unit tesztek nélkül, olcsóbban és gyorsabban fejleszt mobil alkalmazást, mint azt a hagyományos fejlesztő csapat tenné.
Mi az a Unit teszt?
Az egységtesztek (unit tesztek) olyan tesztek, amelyeket az alkalmazás legkisebb egységeire alkalmaznak. Ezek a tesztek az egyes kódrészletek működését ellenőrzik elkülönítve a többi résztől.
Mire való a Unit teszt?
A unit tesztek két fő célt szolgálnak:
- Funkcionális működés ellenőrzése: Az egységtesztek segítenek megerősíteni, hogy az egyes egységek megfelelően viselkednek-e az elvárt bemenetekre, és helyesen térnek-e vissza az elvárt kimenetekkel.
- Kódstabilitás fenntartása: Az egységtesztek biztosítják, hogy az adott egység működése változatlan maradjon a fejlesztés során. Ha egy kódrészletet módosítanak, az egységtesztek segítenek abban, hogy az új változtatások ne befolyásolják a már meglévő funkcionalitást.
Ki készíti el, és hogyan?
Optimális esetben a unit teszteket a fejlesztő írja a saját érdekében. Többnyire az eredeti nyelven írt kódra kell gondolni, léteznek azonban más megoldások, akár szövegesen leírt mondatokból is elképzelhető automatizált unit teszteket készíteni.
Szinte minden esetben az implementációt megelőzően szokás megírni a teszteket. Majd azok alapján implementálni (lásd.: TDD, BDD).
Mit ér a Unit teszt?
Mint fent említettem a unit teszt célja, hogy a funkciók helyesen működjenek. Úgy tudjuk őket elképzelni, mint konkrét példákat. Bizonyos bemenetekre, bizonyos értékeket várunk. A szoftverfejlesztés kezdeti szakaszában ezeknek a szabályoknak rendelkezésre kellene állniuk, hiszen szükségesek ahhoz, hogy a fejlesztő értse a megrendelő igényeit.
Tehát ezzel még az implementációt megelőző szakaszban fény derülhet a specifikáció hiányosságaira. A domain specialistákat pedig arra sarkallja, hogy gondoljanak bele pontosan hogyan működik az implementálni kívánt funkció.
Ez egy hatalmas előny. Egy részt korai visszajelzést ad a hibás vagy hiányos specifikációról. Másrészt dokumentál, így egy esetleges későbbi fejlesztő számára nagy segítség lehet. Garancia arra, hogy valóban az történik amit a megrendelő elvárt, és igazi biztonság érzetet ad a kód későbbi módosításánál a fejlesztőnek.
Garantáltan hiba mentes lesz-e a kód?
Amit eddig elmondtam csodálatos, már-már idealizált képet fest a unit tesztekről. De mit jelent pontosan a garantáltan helyes működés? A legtöbb ember tévesen arra asszociál, hogy ezáltal a kód már-már hibátlan lesz. Soha nem fog “eltörni” a program.
A unit teszt azonban nem erre ad garanciát. A garantáltan helyes működés kizárólag azt jelenti, hogy a specifikáció által támasztott üzleti követelményeknek megfelelő eredményt fog szolgáltatni.
Magyarul: ha van egy bemenetem amivel műveletet szeretnék végezni, és annak a műveletnek lesz egy eredménye, akkor az biztosan helyes eredmény lesz. Tehát nem olyan problémáktól lesz mentes a szoftver, amik futás idejű “összeomlott a program” jellegű hibák, hanem olyanoktól, amikor működne a szoftver csak nem az történik, amit elvárunk tőle.
Na most akkor ez mit ér?
Nyilván úgy működik, nem? Hát sajnos nem. Ugyanis két dolog történhet:
Rosszul értette meg a fejlesztő a domaint.
Hiszen annak, aki kiadja a feladatot bizonyos információk magától értetődőek. pl.: “Jaa én azt hittem, hogy ennek így kell működnie. Honnan tudtam volna, hogy a helyben fogyasztott étel ÁFA kulcsa nem 27%, míg az alkoholé igen.”
Szintén gyakori, hogy a feladatot kommunikáló személy azt hiszi, hogy 100%-ban érti a feladatot, ez elsőre igaznak is tűnik, de közben kiderül, hogy vannak olyan szélső esetek, amikbe nem gondolt bele.
Módosítani kell a kódon, de már mindenre nem emlékszik a fejlesztő
Valljuk be ez indokolatlan nyomást helyez a fejlesztőre. 1-2 évre visszamenőleg nem lehet minden művelet összes teszt esetére emlékezni, és akár egy idő nyomás alatt lévő hiba javításnál ki is próbálni.
Ezt súlyosbítja, hogy ezek a műveletek most egyszerűnek hatnak, de gyakran a felhasználó sok művelet együttes eredményét látja a képernyőn, és ez egy-egy kisebb műveletben ejtett logikai hibát egyrészt elrejt, másrészt nehezen lokalizálhatóvá tesz.
Mennyi idő mindez?
Akkor végülis lehet hasznos, de most mennyi időbe kerül mindez? Ez természetesen sok tényező függvénye. Konkrét számot nehéz rá kalkulálni, és hatalmas mértékben függ mind a programozási nyelvtől mind az alkalmazott paradigmától. Azért ha belegondolunk abba, hogy a tesztek konkrét esetekre adott konkrét értékek vizsgálata, olyan teszteké, amik egyébként is fel kell merüljenek a fejlesztés során, ezek leírása egy jó nyelvben nem okoz hatalmas idő többletet, sem lelki törést.
A legnagyobb probléma mégis az, ha a fejlesztő idő szűkében van. A megrendelő abszolút jogosan működő alkalmazást szeretne látni, nem pedig láthatatlan unit teszteket.
Így ha valaki elkezd egy fejlesztést, és nem ír tesztet, természetesen gyorsabban kezdhet neki az implementációnak és előbb lesz bemutatható eredmény is. Az, hogy egy művelet nem garantáltan működik helyesen, nem jelenti azt sem, hogy rosszul működik.
Azonban általában egy szoftvert nem pár hónap alatt készítünk. És nem az a cél, hogy soha többé ne érjünk majd hozzá… Ahogy pedig telik az idő, az alkalmazás egyre komplexebb és nehezebben fejben tarthatóvá válik. Így összességében én mindenkinek azt javaslom, hogy fordítson időt és energiát a unit tesztekre, mert ami kezdetben idő veszteség, a fejlesztés egy későbbi időciklusában idő nyereséggé válhat. Ahhoz pedig elengedhetetlen, hogy valaki az általa készített szoftvert megbízhatónak nevezze.