
Business & Integration IT konzultant
Unit testing je typ testovania softvéru, ktorý sa zameriava na jednotlivé malé časti kódu alebo komponenty softvérového systému. Cieľom unit testovania je overiť, či každá malá časť – jednotka softvéru funguje tak, ako má a či spĺňa požiadavky. Unit testovanie zvyčajne vykonávajú developeri a vykonáva sa na začiatku vývojového procesu pred tým, ako sa kód integruje a testuje sa ako celok.
Unit testy sú automatizované a vykonávajú sa pri každej zmene kódu, aby sa zabezpečilo, že nový kód neporuší existujúcu funkčnosť. Unit testy sú navrhnuté tak, aby overovali najmenšiu možnú jednotku kódu, napríklad funkciu alebo metódu a testovali ju izolovane od zvyšku systému. To umožňuje vývojárom rýchlo identifikovať a opraviť prípadné problémy už na začiatku procesu vývoja, čím sa zlepšuje celková kvalita softvéru a skracuje sa čas potrebný na neskoršie testovanie.
Pri diskusii o unit testovaní je nevyhnutné rozlišovať medzi unit testami a integračnými testami. Zatiaľ čo unit testy sa zameriavajú na testovanie jednotlivých komponentov alebo jednotiek kódu izolovane, integračné testy overujú interakcie medzi týmito jednotkami a zabezpečujú, aby fungovali spoločne podľa očakávania.
V STLC (SDLC) alebo V modeli je unit testovanie prvou úrovňou testovania vykonávanou pred integračným testovaním.
Existujú 2 typy unit testovania: manuálne a automatizované.
Manuálne unit testovanie predstavuje praktický prístup, pri ktorom testeri píšu a vykonávajú testovacie prípady bez pomoci nástrojov na automatizáciu alebo unit testovanie. Tento typ unit testovania je často flexibilnejší a v určitých súvislostiach môže byť výstižnejší. Vo všeobecnosti je však časovo náročnejší a náchylnejší na ľudské chyby.
Automatizované unit testovanie:
Vývojár napíše časť kódu v aplikácii len na otestovanie funkcie. Neskôr testovací kód zakomentuje a nakoniec odstráni, keď je aplikácia nasadená. Pomocou automatizačného frameworku vývojár programuje do testu kritériá na overenie správnosti kódu. Počas vykonávania testovacích prípadov framework zaznamenáva neúspešné testovacie prípady. Mnohé frameworky tieto neúspešné testovacie prípady aj automaticky označia a súhrnne nahlásia. V závislosti od závažnosti zlyhania môže framework zastaviť ďalšie testovanie.
Pracovný postup unit testovania je nasledovný: 1) Vytvorenie testovacích prípadov 2) Preskúmanie 3) Základné hodnotenie 4) Vykonanie testovacích prípadov
Existujú 3 typy metód unit testovania. Sú to:
Testovanie čiernej skrinky (Black Box Testing): Táto technika testovania sa používa pri testovaní komponentov pre vstupné, používateľské a výstupné časti.
Testovanie bielej skrinky (White Box Testing): Táto technika sa používa pri testovaní funkčného správania systému zadaním vstupu a kontrolou výstupu funkčnosti vrátane vnútornej štruktúry návrhu a kódu modulov.
Testovanie šedej skrinky (Gray Box Testing): Táto technika sa používa pri vykonávaní príslušných testovacích prípadov, testovacích metód a testovacích funkcií a pri analýze výkonu kódu modulov.
Testovacie predpoklady sú komponenty unit testu zodpovedné za prípravu prostredia potrebného na vykonanie testovacieho prípadu. Sú to predpoklady a nastavenia, ktoré potrebuješ na spustenie testovacích prípadov. Nazývajú sa aj „testovací kontext“ a vytvárajú počiatočné stavy pre testovanú jednotku, aby sa zabezpečilo jej kontrolovanejšie vykonávanie. Sú veľmi dôležité, pretože poskytujú konzistentné prostredie na opakovanie procesu testovania.
Povedzme napríklad, že máme blogovaciu aplikáciu a chceme otestovať modul vytvárania príspevkov. Testovacie predpoklady by mali obsahovať:
Unit testovací prípad je jednoducho časť kódu navrhnutá na overenie správania inej jednotky kódu, čím sa zabezpečí, že testovaná jednotka funguje podľa očakávania a prináša požadované výsledky. Tu je napríklad prípad unit testu (unit test example) funkcie, ktorá počíta súčet dvoch čísel a a b:
use PHPUnit\Framework\TestCase;
class MathTest extends TestCase {
public function testSum() {
// Premenné
$a = 5;
$b = 7;
$expectedResult = 12;
// Funkcia
$result = Math::sum($a, $b);
// Assertion - tvrdenie
$this->assertEquals($expectedResult, $result);
}
}
Tvrdenie použité v tomto kóde je $this->assertEquals($expectedResult, $result); overuje, že a + b sa skutočne rovná očakávanému výsledku 12.
Test runner je framework na organizovanie vykonávania viacerých unit testov a tiež na poskytovanie hlásení a analýzu výsledkov testov. Dokáže prehľadávať kódovú bázu alebo adresáre, aby vyhľadal testovacie prípady a následne ich vykonal. Skvelé je, že test runner môže spúšťať testy podľa priority a zároveň spravovať testovacie prostredie a obsluhovať operácie nastavenia/odstavenia. Vďaka testovaciemu runneru môže byť testovaná jednotka izolovaná od externých závislostí.
Testovacie dáta by sa mali starostlivo vyberať tak, aby pokrývali čo najviac scenárov danej jednotky, čím sa zabezpečí vysoké pokrytie testami. Vo všeobecnosti sa očakáva príprava dát pre:
Mocking a stubbing sú v podstate náhradami skutočných závislostí testovanej jednotky. Pri testovaní jednotiek sa vývojári musia sústrediť na izolované testovanie konkrétnej jednotky, ale v určitých scenároch budú na vykonanie testu potrebovať dve jednotky.
Napríklad môžeme mať triedu User, ktorá závisí od externej triedy EmailSender na odosielanie e-mailových oznámení. Trieda User má metódu sendWelcomeEmail(), ktorá zavolá EmailSender na odoslanie uvítacieho e-mailu novo zaregistrovanému používateľovi. Ak chceme metódu sendWelcomeEmail() otestovať izolovane bez skutočného odosielania e-mailov, môžeme vytvoriť maketový objekt triedy EmailSender. Vývojár sa potom nebude musieť starať o to, či externá jednotka (EmailSender) funguje dobre alebo nie. Testovaná jednotka je skutočne testovaná izolovane.
Tu sú niektoré bežne používané nástroje na unit testovanie:
Jednotka môže byť takmer čokoľvek, čo chceš – riadok kódu, metóda alebo trieda. Vo všeobecnosti však platí, že menšie je lepšie. Menšie testy ti poskytnú oveľa detailnejší pohľad na to, ako tvoj kód funguje. Je tu aj praktický aspekt, že keď testuješ veľmi malé jednotky, testy môžu byť spustené rýchlo, napríklad tisíc testov za sekundu.
Zoberme si túto ukážku kódu:
def divider (a, b)
return a/b
end
Pri použití jazyka Ruby by tieto malé testy mohli vyzerať takto:
class smallTest < MiniTest::Unit::testCase
def tiny_test
@a=9
@b=3
assert_equal(3, divider(a, b))
end
end
Tento príklad je príliš jednoduchý, ale dáva v predstavu o tom, čo myslím pod pojmom malý. Ak si chceš pozrieť priamy postup vytvárania unit testu, klikni sem unit test tutorial.
Unit testy zvyčajne pozostávajú z troch fáz:
Základnou vecou, ktorú je potrebné zvážiť pri písaní testu, je výber názvu testu. Dobré názvy testov zlepšujú čitateľnosť kódu tak pre programátora, ako aj pre ostatných, ktorí môžu na tomto kóde v budúcnosti pracovať. Existujú štandardné konvencie pre pomenovanie (viac si prečítaj tu – unit test naming convention), ktoré je možné použiť pri unit testovaní.
Udržiavanie čo najjednoduchších kódov testov je kľúčom k zachovaniu ich správnosti. Unit testovacie kódy môžu mať aj chyby, najmä pri vysokej úrovni zložitosti.
Deterministický test dáva vždy rovnaký výsledok bez ohľadu na vstup, pokiaľ sa kód nemení. Tým sa minimalizuje výskyt falošne pozitívnych a falošne negatívnych výsledkov. Testy musia byť deterministické, pretože testu, ktorý prezentuje premenlivé výsledky, nemožno dôverovať.
Každý test by sa mal použiť na testovanie jedného prípadu použitia. Konkrétny testovací program by mal testovať jeden blok kódu. Tým sa overí výstup a získa sa lepší prehľad o príčine objavených chýb bez pochybností o tom, odkiaľ pochádzajú.
Vývojári by mali kompletne a dôkladne otestovať softvérovú aplikáciu v čo najväčšom rozsahu. Nie vždy je to však uskutočniteľné vzhľadom na časové a finančné požiadavky. Napriek tomu sa vývojári musia snažiť vykonávať unit testy programu v čo najväčšej miere.
Pomalé testy sú pre vývojárov zložité na vykonávanie. Spomaľujú proces a nedajú sa často používať. Pripúšťame, že rýchlosť testu je subjektívna a závisí od testovaného predmetu, ale každý test, ktorý trvá viac ako hodinu a 15 minút, možno klasifikovať ako pomalý.
Hoci unit testy možno vykonávať manuálne, súčasné postupy podporujú automatizovanú metódu testov. Ukázalo sa, že je nielen efektívnejšia a lacnejšia ale aj časovo úspornejšia.
Testy vytvorené pred niekoľkými mesiacmi už nemusia platiť. Je veľmi dôležité vykonávať testy pravidelne, pretože zmeny v požiadavkách a kóde môžu spôsobiť problémy, ktoré nezodpovedajú tomu, čo by mali testovať. Zanedbanie aktualizácie testov môže viesť k falošným alebo zavádzajúcim výsledkom.
Riešenie: Pravidelné vykonávanie testov je nevyhnutné. Najlepšie pomocou automatizovaného unit testovania. Mal by si sa tiež uistiť, že sú v súlade s požiadavkami.
Jednou z hlavných chýb pri unit testovaní je nenájdenie správnej rovnováhy. Testovanie každého riadku kódu môže byť vyčerpávajúce a časovo náročné, zatiaľ čo pri testovaní príliš malého počtu častí môže dôjsť k prehliadnutiu kritických chýb. Je nevyhnutné zamerať sa na testovanie najdôležitejších funkcií a okrajových prípadov.
Riešenie: Na identifikáciu častí kódu, ktoré potrebujú najviac testovania, použi techniky, ako je analýza pokrytia kódu a hodnotenie rizík. Uprednostni testovanie zložitých funkcií, oblastí náchylných na chyby a funkcií zameraných na používateľa.
Použitie nesprávnych alebo nevhodných údajov na testovanie môže viesť k zavádzajúcim výsledkom. Takýmito príkladmi sú falošne pozitívne alebo negatívne výsledky. Napríklad vykonávanie testov s použitím nulových hodnôt by mohlo zakryť skutočné chyby alebo odlišné scenáre. Podobne vykonávanie testov s príliš podobnými a veľmi náhodnými údajmi by mohlo znížiť účinnosť a transparentnosť tvojich testovacích procesov.
Riešenie: Je nevyhnutné používať praktické a inkluzívne údaje, ktoré zahŕňajú rôzne situácie a vstupy. Na tento účel použi generátory údajov a kontrolu testovacích údajov, čím zabrániš opakovaniu.
Významným úskalím pri unit testovaní je kontrola nesprávnych aspektov alebo vyhodnocovanie niečoho, čo nie je jednotkou. Vyhodnocovanie komponentov, ktoré nie sú jednotkami, ako sú databázové dotazy, volania webových služieb alebo používateľské rozhrania, vedie k nespoľahlivým a pomalým testom, ktoré sa spoliehajú na externé prvky.
Riešenie: Na efektívne unit testovanie použi mocking a stubs. Tieto techniky simulujú závislosti jednotky, čím vytvárajú kontrolované prostredie, ktoré izoluje jednotku od väčšieho systému.
Vynechanie testovacích recenzií znamená, že sa vynechá zdieľanie osvedčených postupov a zvyšuje sa pravdepodobnosť výskytu testovacích chýb. Recenzie kódu zvyšujú kvalitu unit testov v tíme.
Riešenie: Pre optimálne výsledky vykonávaj priamo review kódu, či už osobne alebo prostredníctvom zdieľania obrazovky.
Vkladanie logiky do unit testov komplikuje ich čitateľnosť a údržbu a zvyšuje riziko chýb. Ak tvoj unit test obsahuje logiku, naznačuje to, že možno nevytváraš správne unit testy.
Riešenie: V prípade, že sa v testovacích jednotkách nachádza nejaká chyba, je potrebné ju odstrániť: Obmedz počet tvrdení (assertions) v každom teste. Ak máš príliš veľa tvrdení, údržba sa stáva náročnou.
Jedným zo spoľahlivých spôsobov, ako mať unit testy, ktorých spustenie trvá večnosť, je napísať unit testy, ktoré robia veci ako zápis súborov na disk alebo vyťahovanie informácií z databáz. Vyhni sa teda používaniu externých prvkov, pretože to spomalí test a aj preto, že keď to robíš, v skutočnosti nepíšeš unit testy. Unit testy sú cielené kontroly, ktoré izolujú kód a tvrdia, ako sa má správať. Kontroluj veci ako „ak metóde add(int, int) podám 2 a 2, vráti 4?“. To je rozsah unit testu.
Riešenie: Riešenie je jednoduché. Netestovať databázy, zápis na disk a podobne, testovať len malé časti kódu.
Ako vidíš, unit testovanie môže byť veľmi náročné. Testovanie komponentov je ale na určitej úrovni vždy potrebné. To je isté.
Ak sa chceš otestovať vo svojich znalostiach o unit testoch, alebo sa pripravuješ na pohovor, určite nepreskoč tento zoznam najčastejších otázok a odpovedí – unit test questions for interview.
Ak vieš po nemecky a hľadáš si prácu ako IT tester alebo automatizovaný tester, prezri si naše benefity pre zamestnancov a reaguj na najnovšie ponuky práce.