Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

4. diel - Testovanie v Pythone - Unit testy - Test analyzeru tagov

V minulej lekcii, Testovanie v Pythone - PyHamcrest a best practices , sme si predstavili knižnicu PyHamcrest, vysvetlili si očakávané chyby a nakoniec spomenuli aj best practices pre testovanie.

Aby sme nezostali len pri testoch našej kalkulačky, ukážeme si v niekoľkých ďalších lekciách kódy unit testov z reálnych aplikácií. Pôjde o testy analyzátora správ, perzistentné vrstvy (ukladanie dát) ao testy generátora náhodných tokenov. Pomôžu vám pre lepšiu predstavu ako sa takéto veci testujú v praxi.

Pozn.: Príklady budú mať postupne zložitejší a zložitejší kód. Nelámte si hlavu s tým, pokiaľ nebudete rozumieť niečomu v ich implementácii. Mali by ste pochytiť najmä spôsob testovania, teda čo ktorý test overuje a ako to overuje.

Test analyzeru tagov

Nasledujúci test overuje správnu funkčnosť triedy TestTagAnalyzer. Tá analyzuje správu a hľadá v nej hashtagy, ako ich poznáte napr. z Facebooku ("Zas som zaspal. #pondelky").

Štruktúra testovacej triedy

Ukážme si základnú štruktúru testovacej triedy s inicializáciou a popíšme si ju nižšie:
import unittest
import re

class TestTagAnalyzer(unittest.TestCase):

    msg_no_tags = "Nějaká zpráva standardní délky neobsahující žádné tagy."
    msg_single_tag = "Zpráva obsahující jeden #tag."
    msg_only_tags = "#zprava #sestavena #z #tagu."
    msg_hashes = "######################"

    dict_no_tags = {msg_no_tags: []}
    dict_single_tag = {msg_single_tag: ['tag']}
    dict_only_tags = {msg_only_tags: ['zprava', 'sestavena', 'z', 'tagu']}
    dict_hashes = {msg_hashes: []}

Vidíme, že trieda deklaruje 4 testovacie správy. Prvú úplne bez hashtagov, druhú s jedným hashtagom na konci, tretiu vytvorenú len z hashtagov a štvrtú zloženú iba z hashkrížov. Túto praktiku sme si už spomínali, ak by sme všetko testovali len na jednej obyčajnej správe, mohlo by sa stať, že by analyzer zle fungoval v medzných prípadoch. To sú prípady, keď v správe nie je žiadny hashtag alebo je naopak plná hashtagov. Tu počítame aj so situáciou, kedy sú použité znaky pre hashtagy, ale nejde o skutočný hashtag. Všetky tieto situácie by mal testovaný analyzer zvládnuť.

Pre každú správu si následne vytvoríme zoznam tagov, ktoré v nej má analyzer nájsť. Na to slúžia slovníky. Ako kľúče v slovníkoch použijeme jednoducho jednotlivé správy. A ako hodnoty k nim vytvoríme zoznam tagov, ktoré by v nich analyzer mal nájsť. V prvej správe žiadne tagy nie sú, v tej druhej je tag " tag ", v tretej sú tagy " zprava ", " sestavena ", " z ", " tagu ". V tej poslednej opäť žiadne tagy nie sú.

Testovacie metódy

To by bolo k inicializácii, presuňme sa k samotným testom. Opäť si najskôr ukážme zdrojový kód:
def test_analyze_tags_no_tags(self):
     tag_list = re.findall(r'#([a-z0-9]+)', self.msg_no_tags)
     expected = self.dict_no_tags[self.msg_no_tags]
     assert tag_list is not None
     assert tag_list == []


 def test_analyze_tags_single_tag(self):
     tag_list = re.findall(r'#([a-z0-9]+)', self.msg_single_tag)
     expected = self.dict_single_tag[self.msg_single_tag]
     self.assertEqual(tag_list, expected)
     assert tag_list is not None


 def test_analyze_tags_none(self):
     with self.assertRaises(TypeError):
         tag_list = re.findall(r'#([a-z0-9]+)', None)


 def test_analyze_tags_only_tags(self):
     tag_list = re.findall(r'#([a-z0-9]+)', self.msg_only_tags)
     expected = self.dict_only_tags[self.msg_only_tags]
     self.assertEqual(tag_list, expected)
     assert tag_list is not None


 def test_analyze_tags_hashes(self):
     tag_list = re.findall(r'#([a-z0-9]+)', self.msg_hashes)
     expected = self.dict_hashes[self.msg_hashes]
     assert tag_list is not None
     assert tag_list == []

Máme tu 5 testovacích metód. Popíšme si ich:

  • test_analyze_tags_no_tags() - Nechá zanalyzovať prvú správu. Nesmie vrátiť None. List, ktorý vráti, musí byť prázdny.
  • test_analyze_tags_single_tag() - Metóda si nechá získať tagy z druhej vety a následne porovná, či je list nájdených tagov totožný s expected ako vo vzorovom slovníku. Kontroluje tiež, či nevráti hodnotu None.
  • test_analyze_tags_none() - Otestuje, že analyzer vyvolá výnimku v prípade, ak mu namiesto reťazca so správou príde hodnota None. Ošetrovanie hodnôt None je v Pythone veľmi dôležité, ušetrí vám veľa nepríjemností v budúcnosti, kde sa nejakým nedopatrením None do analyzeru napríklad dostane. Keďže vyvolá okamžite výnimku, problém rýchlo odhalíte. Časom zistíte, že aj keď tieto "impossible" kontroly nemôžu vyskočiť, tak aj tak občas vyskočia.
  • test_analyze_tags_only_tags() - Metóda funguje úplne rovnako ako druhá metóda.
  • test_analyze_tags_hashes() - Funguje rovnako ako prvá metóda.

Pozn.: Určite ste si všimli, že je test trochu redundantný. V podstate sa tu opakujú 2 metódy. Ak by bol ešte dlhší, vyplatilo by sa vytvoriť pre tieto 2 akcie vlastné metódy. Tu bol úmyselne ponechaný rozpísaný príklad, aby počet metód zodpovedal počtu testov.

Test si môžeme vyskúšať nám už známym príkazom:

python -m unittest

Alebo lepšie podrobnejším príkazom:

python -m unittest -v nazev_souboru_s_testem.py

A je hotovo. Teraz môžeme analyzer tagov ľubovoľne prepisovať a pokiaľ test opäť prejde, môžeme si byť takmer istí, že sme ho nerozbili.

Z testu by sme si mali odniesť:

  • Testujeme či objekt reaguje korektne na hodnoty None
  • Testujeme medzné hodnoty
  • Akokoľvek komplikované požadované výstupy vytvárame vopred ako referenčné hodnoty a tie potom porovnávame so skutočným výstupom metódy
  • Píšeme impossible asserty av objektoch vyvolávame impossible výnimky

Tieto prvé testy boli pomerne jednoduché. Ako už bolo povedané v úvode, čakajú nás ešte dvaja rozsiahlejší.


 

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é 7x (668 B)
Aplikácia je vrátane zdrojových kódov v jazyku Python

 

Predchádzajúci článok
Testovanie v Pythone - PyHamcrest a best practices
Všetky články v sekcii
Testovanie v Pythone
Článok pre vás napísal Patrik Bernat
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Aktivity