3. diel - Testovanie vo VB.NET - Dokončenie unit testov a best practices
V minulej lekcii, Testovanie vo VB.NET - Úvod do unit testov a príprava projektu , sme si pripravili jednoduchú triedu a vygenerovali testovací projekt s potrebnou referenciou.
V dnešnom tutoriále Testovania vo VB .NET pokryjeme testy našu jednoduchú triedu. Uvedieme si dostupné asserčné metódy a unit testy vo VB .NET dovŕšime prehľadom best practices.
Jednotlivé metódy budeme vždy označovať atribútom
<TestMethod>
. Zaistíme tým, že sa bude testovať jedna
konkrétna metóda z triedy Kalkulacka
. Typicky pre niekoľko
rôznych vstupov.
Metódy označujeme atribúty. Umožňuje nám
to vytvoriť si aj pomocné metódy, ktoré môžeme v danom
teste využívať. Nebudú pokladané za testy. Visual Studio nám totiž testy
(metódy s anotáciou <TestMethod>
) automaticky spustí a
vypíše ich výsledky.
Metódy triedy
KalkulackaTests
Do nášho projektu (do triedy KalkulackaTests
) pridáme pod
metódu Cleanup()
päť nasledujúcich metód:
Na porovnávanie výstupu
metódy s očakávanou hodnotou používame statické metódy
na triede Assert
. Najčastejšie používame metódu
AreEqual()
prijímajúcu v prvom parametri očakávanú
hodnotu av druhom parametri hodnotu aktuálnu.
Poradie parametrov je dobré dodržiavať, inak budeme mať hodnoty vo výsledkoch testov opačne.
Desatinné čísla sú v pamäti počítača reprezentované binárne (ako inak:) ). To spôsobí určitú stratu ich presnosti, a tiež určité ťažkosti pri ich porovnávaní. Preto musíme v tomto prípade zadať aj tretí parameter. Týmto parametrom je delta, teda kladná tolerancia. O koľko sa môže očakávaná a aktuálna hodnota líšiť, aby test stále prešiel.
Skúšame rôzne vstupy. Sčítanie netestujeme len ako
1 + 1 = 2
. Skúšame celočíselné,
desatinné aj negatívne vstupy. Všetko
oddelene s overením výsledkov. V niektorých prípadoch by nás mohla
zaujímať aj maximálna hodnota dátových typov a podobne.
Posledný test overuje, či metóda Vydel()
naozaj vyvolá
výnimku pri nulovom deliteľovi. Nemusíme sa zaťažovať s
try-catch
blokmi. Stačí nad metódu pridať atribút
<ExpectedException>
. Uviesť tu typ
výnimky, Ktorá sa očakáva. Ak výnimka nenastane, test zlyhá. Na
testovanie viacerých prípadov vyvolania výnimky môžeme použiť ďalšie
assert metódy, viď nižšie.
Dostupné Assert
metódy
Bolo by vhodné spomenúť, že sa porovnáva s ohľadom na dátové typy.
Teda 10L
(long
) je iná hodnota, než 10
(int
). Okrem metódy AreEqual()
môžeme použiť
ešte mnoho ďalších. Snažíme sa použiť tú najviac vyhovujúcu metódu.
To totiž sprehľadňuje hlášky pri zlyhaní testov a
samozrejme aj následnú opravu.
Uveďme si niektoré dostupné Assert
metódy:
AreNotEqual()
- Používame ak chceme overiť, že sa 2 objekty NEzhodujú. Ďalšie metódy sNot
tu už nebudeme zbytočne spomínať.AreSame()
- Skontroluje či 2 referencie ukazujú na rovnaký objekt (porovnáva pomocou operátora==
).Equals()
- Používame v prípade ak chceme overiť 2 objekty pomocou metódyEquals()
a zistiť či sú rovnaké. Nepoužívame na overenie hodnoty miestoAreEqual()
.Fail()
- Spôsobí zlyhanie testov. Obvykle ju vkladáme za nejakú podmienku. Dopĺňame o voliteľné parametre (chybové hlásenie a parametre).Inconclusive()
- Funguje podobne akoFail()
. Vyvolá výnimku signalizujúcu nepreukaznosť testu.IsFalse()
- Overí, či je daný výraz NEpravdivý.IsInstanceOfType()
- Overí, či je objekt inštancií daného typu.IsNull()
- Overí, či je hodnotanull
.IsTrue()
- Overí, či je daný výraz pravdivý.ReplaceNullChars()
- Nahradí nulové znaky\0
za\\0
. Využijeme najmä pri diagnostických výpisoch reťazcov s týmito znakmi.ThrowsException()
- Spustí odovzdaný delegát a overí, že vyvoláva výnimku odovzdanú ako generický argument. Metóda má aj asynchrónnu verziuThrowsExceptionAsync()
.
ReferenceEquals()
. Nie je
súčasťou testov, ale je štandardne na všetkých triedach.
Spustenie testov
Testy spustíme z menu Test -> Run All Tests:
Uvidíme výsledky, ktoré vyzerajú takto:
Skúsme si teraz urobiť v kalkulačke chybu. Napr. zakomentujme vyvolávanie
výnimky pri delení nulou a vráťme vždy hodnotu 1
:
A spustite znovu naše testy:
Vidíme, že chyba je zachytená. Sme na ňu upozornení. Neprešiel ako test delenia, tak test vyvolania výnimky. Môžeme kód vrátiť späť do pôvodného stavu.
Best practices
Už v minulej lekcii sme načali best practices. Toto je k unit testom vo VB .NET všetko. Poďme si na záver vymenovať akých častých chýb sa vyvarovať, aby sme dosiahli kvalitný výsledok.
Špecifikácia testov
Testy nikdy nepíšeme podľa kódu nejakej metódy. Zamýšľame sa nad tým, na čo metóda reálne slúži. Tiež nad tým čo všetko ju môže prísť ako vstup.
Testovanie všeobecných knižníc
Netestujeme konkrétnu logiku aplikácie. Ak je logika dôležitá a všeobecná, mala by byť vyčlenená do samostatnej knižnice. Tá by mala byť potom testovaná.
Nezávislosť testov
Každý test by mal byť úplne nezávislý od ostatných testov. Scenár by mal prebehnúť aj keď metódy ľubovoľne prehádžeme. Žiadna metóda by po sebe nemala zanechávať nejaké zmeny (v súboroch, v databáze a podobne), ktoré by ovplyvnili ďalšie metódy. Na dosiahnutie tohto správania často pripravujeme prostredie pre jednotlivé metódy v inicializačnej metóde. Prípadne po nich ešte vykonáme upratovanie v metóde upratovacej. To isté platí aj pre celé testy.
Stabilita testov
Každý test by mal dopadnúť vždy rovnako. Bez ohľadu na to, kedy ho spustíme. Pozor na testovanie generátorov náhodných výstupov a na prácu s dátumom a časom.
Duplicitné porovnanie
Pokiaľ nejaký vstup už overuje iný test, nevykonávajme toto overenie znova.
Jednotkové testy a návrh softvér
Náš softvér by mal byť navrhnutý tak, aby bol rozdelený na menšie triedy. Tie majú minimálne závislosti na ostatných. Preto sa dajú jednoducho a nezávisle testovať (vzory high cohesion a low coupling).
Externé služby
Mali by sme ich tzv. mockovať. Tým vytvárame „falošné“ služby s rovnakým rozhraním, ktoré obvykle len podstrkujú testovacie dáta. Využitím skutočných služieb by sme porušili nezávislosť testov, pretože by sa navzájom začali ovplyvňovať. Menej elegantné riešenie je, vždy na začiatku nastaviť a na konci vrátiť stav služieb.
Názvy testov
Vyhnime sa zavádzajúcim názvom testov (ako
vypocet()
, vyjimka()
a podobne). Programátori často
pomenovávajú testy aj väčším počtom slov, aby sa poznalo čo robia.
Bežne by sme to pri metódach nemali robiť, pretože každá metóda robí len
jednu činnosť. Niekedy pri testoch dáva zmysel pomenovať metódy napr. aj
takto obskurne KvadratickaRovnice_ZaporneKoeficienty_Vyjimka()
.
Test často testuje viac vstupov. Ideálne by mal názov testu
obsahovať názov metódy, ktorú testuje. V pomenovávaní testov by
sme mali byť konzistentné. Nebojme sa ani komentárov.
Rýchlosť testov
V praxi obvykle testujeme všetky časti aplikácie rôznymi typmi testov a všetky časy sa dokážu nasčítať do nepríjemnej pauzy.
Naše prvé unit testy nemusia byť perfektné. Stačí krátko otestovať to najdôležitejšie. Časom sa začnú odhaľovať chyby v implementácii. Čím je aplikácia väčšia, tým o väčšie pokrytie testami (test code coverage) by sme sa mali snažiť.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 3x (2.17 MB)
Aplikácia je vrátane zdrojových kódov v jazyku VB.NET