11. Testování

Testování #

Osnova cvičení #

  • Zkusíte vymyslet testovací případy pro knihovnu, ke které máte pouze hlavičkové soubory (black box testing),
  • Zkusíte vymyslet vstupní testovací data pro otestování pokrytí kódu pomocí nástroje lcov.

Příprava prostředí #

Pro část 1 nebudete potřebovat nic nového. Pro část 2 si potřebujete stáhnout nástroj lcov. Na stolní počítače nemůžete nic bohužel instalovat, musíte na vlastním notebooku.

Pro Ubuntu:

sudo apt install lcov

Pro Fedora:

sudo dnf install lcov

Pro MacOS:

brew install lcov

Část 1 (Black box module testing) #

Budete testovat správnost implementace bankomatu, k jehož logice a správě dostupných uživatelů ale nemáte přístup, máte jedině přístup k hlavičkovému souboru, který definuje operace nad bankomatem (takzvaný “interface”).

Vašim úkolem je vymyslet testovací případy, které otestují správnost implementace bankomatu. Implementace bankomatu má stav, je tedy potřeba dělat operace na bankomatu v konkrétním pořadí (v reálu se nejdříve autorizuje uživatel dle pinu, poté vybere peníze).

Specifikace interface bankomatu #

Nad bankomatem jsou specifikovány struktury a funkce v hlavičkovém souboru atm.h. Bankomat má oprávněné uživatele podle jejich ID a pinu. V našem případě bankomat pouze podporuje dva uživatele

  • user_id = 20, pin = 4555, balance = 1234,
  • user_id = 30, pin = 9105, balance = 305.

Pravidla fungování bankomatu:

  • k vybrání peněz je potřeba se nejdříve autorizovat správným ID a pinem,
  • jestliže existující uživatel zadá pin 3x, je zablokován, a jakákoli následující přihlášení jsou neplatná (uživatel je stále zablokován),
  • autorizorizovaný uživatel může prohlížet zůstatek jeho konta a také vybírat peníze, jestliže se pokusí vybrat větší zůstatek, než má na účtě, nic se nevybere a zůstatek zůstává stejný.

Bankomat je identifikován datovým typem atm_psy_t. Jedná se o ukazatel na strukturu, k jejíž členům nemáte přístup (tzv. opaque typ) a slouží pouze pro předávání do funkcí operující nad tímto typem (tzv. metody).

K vytvoření instance bankomatu použijte

atm_psy_t *atm_newatm(void).

Po každém testovacím případě byste měli instanci dealokovat pomocí

void atm_dispose(atm_psy_t *atm).

Zbytek funkcí je definován v atm.h.

Zdrojové soubory testovacího programu #

Stáhněte si projekt 11-blackbox.zip.

Projekt obsahuje Makefile, hlavičkový soubor (atm.h) definující interface bankomatu, samotnou implementaci bankomatu v souboru atm*.o a také soubor testenv.c, ve kterém doplníte testovací případy. Soubor testenv.c obsahuje příklad testovacího scénaře, kde se snaží do konta dostat nezaregistrovaný uživatel.

ℹ️ Testovací případy musí být funkce, která je typu bool(void), tedy funkce vracející bool bez parametrů. Funkce vrací true, jestliže případ prošel, false jinak. Použijte macro TEST_CASE, se kterém zavoláte příslušný testovací scénář.

⚠️ Musíte upravit Makefile, aby se slinkovala správná implementace bankomatu. Překlady jsou hotové jak pro x86 Linux, tak pro Apple ARM MacOS. Stolní počítače v učebně mají x86 Linux.

Část 2 (White box testing s nástrojem lcov) #

Nejdříve si nainstalujte lcov, viz výše. Stáhněte si projekt 11-lcov-whitebox.zip.

Program je jednoduchá hra v bludišti. Aby se hra spustila, musí se nejdříve zadat parametry bludiště a začínající pozice hráče. Formát vstupu je následující:

  1. Velikost bludiště n (jedno celé číslo) + newline,
  2. Definice bludiště samotného. Jedná se o n řádek, každá řádka obsahuje n znaků. Každá řádka je oddělena newline.
  3. Následují dvě čísla: pozice x a y, kde bude začínat hráč.

Definice bludiště může obsahovat následující znaky:

  • .: místo, kde se hráč může pohybovat,
  • @: překážka, kam uživatel nemůže jít,
  • *: třešnička.

Hráč nemůže začínat mimo hranice bludiště, na překážce či na třešnicce. Po úspěšném načtení bludiště uživatel zadává příkazy w/a/s/d (pohyb v bludišti). Jakýkoli jiný příkaz skončí hru. Každý příkaz je oddělen enterem.

Váš úkol #

Rozbalte .zip s jednoduchou hrou a projekt přeložte. Vyzkoušejte si hru zahrát. K projektu máte soubor refmaze.txt, kde je bludiště o velikosti 13x13 a začínající pozice x=2, y=2. Program s tímto vstupem (při přesměrování pomocí < refmaze.txt) instantně skončí, protože obsahuje q. Zkopírujte si tedy bludiště do schránky a při spuštění jej pouze skopírujte do standartního vstupu (CTRL+V). Nezapomeňte předtím zadat správnou velikost bludiště a také posléze správnou startovací pozici.

Následně si prohlídněte soubor maze.c a také se zamyslete, co byste chtěli v programu, kdybyste tuto hru programovali (zamyslete se nad překážkami a nad hranicemi bludiště).

Po zamyšlení nad strukturou programu spusťte make lcov a zadejte takovou kombinaci vstupů, abyste v coverage reportu (umístěný v coverage_html/index.html) měli pokryté všechny řádky v funkci

static void gameloop(char *maze, int mazedim, int startx, int starty);

Coverage report obsahuje i pokrytí cest. Správnou kombinací vašeho vstupu se sami přesvěčte, že program reaguje v pořádku. Zkuste také otestovat kontroly vstupů.

ℹ️ Report je ve formátu .html, který musíte otevřít v prohlížeči. Z příkazové řádky lze report otevřít pomocí firefox coverage_html/index.html (nebo také pomocí xdg-open coverage_html/index.html, popř. open coverage_html/index.html pro MacOS).