Ciele
- Oboznámiť sa s významom a druhmi výnimiek v jazyku Java.
- Naučiť sa vytvárať a používať triedy výnimiek definované programátorom.
- Naučiť sa vytvárať unit testy pre aplikáciu pomocou NetBeans IDE.
Úvod
-
Úlohou dnešného cvičenia je oboznámiť sa s významom výnimiek a vyskúšať si ich použitie.
Tiež sa naučíme vytvárať unit testy pre naše aplikácie.
Postup
-
Použite výnimky pri spracovaní vstupov.Úloha: Pridajte do projektu triedu
WrongFormatException
do balíkaminesweeper.consoleui
definujúcu výnimky označujúce zlý formát vstupu. Zdrojový kód danej triedy je WrongFormatException.java.Úloha: V triedeConsoleUI
implementujte súkromnú metóduvoid handleInput(String input) throws WrongFormatException
, ktorá zabezpečí spracovanie vstupného reťazca. Presuňte do tejto metódy existujúce spracovanie vstupného reťazca z metódyvoid processInput()
. V prípade zle zadaného formátu táto metóda vyhodí výnimkuWrongFormatException
.Úloha: Do metódyvoid processInput()
vložte volanie metódyvoid handleInput(String input) throws WrongFormatException
. Použitie príkaztry { ... } catch (WrongFormatException ex) {...}
na odchytenie výnimky a jej spracovanie (vypísanieex.getMessage()
). -
V hre Minesweeper je zvyčajne vypísaný počet neoznačených mín, ktorý je definovaný ako počet všetkých mín v hracom poli mínus počet značiek na označenie míny. Nasledujúcim krokom je preto dodanie tejto podpory do hry.Úloha: Doplňte funkčnosť do metódy
update()
v triedeConsoleUI
, ktorá zabezpečí výpis s uvedením počtu neoznačených mín. Pre získanie počtu neoznačených mín implementujte verejnú metóduint getRemainingMineCount()
v triedeField
. -
Pri realizácii programových systémov vzniká požiadavka testovania funkčných častí ako aj testovania integrácie týchto častí. Pre testovanie programov v prostredí NetBeans je možné použiť nástroj s podporou automatického generovania JUnit testov a ich spúšťania. Cieľom je vytvoriť testy pre testovanie generovania hracieho poľa a overenie implementácie zmien stavov hracieho poľa. Použitie nástroja pre automatické generovanie prototypu testu pre členské metódy vybranej triedy v prostredí NetBeans IDE a ich spustenie je nasledovné.
-
Prostredníctvom kontextového menu nad názvom súboru
Field.java
v záložke „Projects” zvoľte „Tools > Create JUnit Tests”. - V dialógu „Select JUnit Version” zvoľte „JUnit 4.x”.
- Zobrazí sa nasledujúce okno s možnosťou výberu metód na základe ich úrovne viditeľnosti, voliteľného vygenerovania kódu s možnosťou vygenerovania dokumentačných komentárov.
-
Na základe vami zvolených možností sa vygeneruje testovací súbor s množinou testovacích metód. V
prípade, že chcete testovať komplexnejšiu časť ako len jednu metódu triedy Field, jednoducho zmažete
nevyhovujúce vygenerované testovacie metódy, resp. upravte názvy testovacích metód.
Vytvorený testovací súbor bude umiestnený v časti „Test Packages” viditeľný v záložke „Projects” pre
projekt
Minesweeper
. -
Pre spustenie testu sú možné nasledujúce postupy:
- V kontextovom menu nad záložkou projektu zvoliť možnosť „Test Project”.
- V hlavnom menu zvoliť „Run > Test "Minesweeper"”.
Úloha: Vygenerujte pre trieduVo vytvorenej triede FieldTest definujte nasledujúce súkromné konštanty:Field
testovací súborFieldTest
.-
Počet riadkov hracieho poľa:
static final int ROWS = 9;
-
Počet stĺpcov hracieho poľa:
static final int COLUMNS = 9;
-
Počet mín v hracom poli:
static final int MINES = 10;
-
Prostredníctvom kontextového menu nad názvom súboru
-
Skopírujte nižšie uvedenú implementáciu metódy
void isSolved()
do triedyFieldTest
projektu Minesweeper.@Test public void isSolved() { Field field = new Field(ROWS, COLUMNS, MINES); assertEquals(GameState.PLAYING, field.getState()); int open = 0; for(int row = 0; row < field.getRowCount(); row++) { for(int column = 0; column < field.getColumnCount(); column++) { if(field.getTile(row, column) instanceof Clue) { field.openTile(row, column); open++; } if(field.getRowCount() * field.getColumnCount() - open == field.getMineCount()) { assertEquals(GameState.SOLVED, field.getState()); } else { assertNotSame(GameState.FAILED, field.getState()); } } } assertEquals(GameState.SOLVED, field.getState()); }
Poznámka: Uistite sa, že v časti importovania zdrojov je uvedený statický importimport static org.junit.Assert.*;
ako aj import pre anotáciu@Test
uvedený nasledovneimport org.junit.Test;
.Poznámka: Nezabudnite, že každej testovacej metóde musí predchádzať anotácia@Test
.Poznámka: V pripade, že ste predtým nezvolili JUnit 4.x je možné ho pridať aj dodatočne pre projekt. Zvoľte nad projektom v záložke „Projects” v kontextovom menu voľbu „Properties”.Táto metóda testuje implementáciu rozhodnutia či je hra úspešne vyriešená. V prvom kroku je potrebné vytvoriť objektfield
pre hracie pole typuField
, čím sa inicializuje aj počiatočný stav hry. Nad týmto hracím poľom testujeme nasledujúce požiadavky:-
Po vytvorení hracieho poľa musí byť hracie pole v stave priebehu hry -
GameState.PLAYING
. Pre tento typ testu použijeme výrazassertEquals(GameState.PLAYING, field.getState())
. -
Po odkrytí dlaždice typu
Clue
je potrebné testovať stav úspešného ukončenia hry. Ak platí počet všetkých dlaždíc - počet odokrytých dlaždíc = počet mín potom musí byť hra v stave úspešného ukončenia. Pre test úspešného ukončenia hry použijeme výrazassertEquals(GameState.SOLVED, field.getState())
. -
Po odkrytí dlaždice typu
Clue
je potrebné testovať aby nenastal stav neúspešného ukončenia hry. Pre tento typ testu použijeme výrazassertNotSame(GameState.FAILED, field.getState())
. -
Po odkrytí všetkých dlaždíc typu
Clue
musí byť hra v stave úspešného ukončenia hry. Pre tento typ testu použijeme už vyššie uvedený výrazassertEquals(GameState.SOLVED, field.getState())
.
Úloha: Spustite test pre projekt Minesweeper. -
Po vytvorení hracieho poľa musí byť hracie pole v stave priebehu hry -
-
Ďalším z možných testov je testovanie správnosti vygenerovania hracieho poľa (trieda
Field
). Je potrebné otestovať nasledujúce požiadavky na vygenerované hracie pole:-
Počet riadkov, stĺpcov a mín v hracom poli zodpovedá zadaným počtom
assertEquals(ROWS, field.getRowCount())
,assertEquals(COLUMNS, field.getColumnCount())
,assertEquals(MINES, field.getMineCount())
. -
Každá položka hracieho poľa musí byť reprezentovaná dlaždicou a nesmie byť rovná hodnote
null
. Pre každú položku hracieho poľa je teda potrebné testovať výrazassertNotNull(field.getTile(row, column))
, kde premennáfield
je objektom hracieho poľa typuField
. -
Počet vygenerovaných dlaždíc typu
Mine
musí byť zhodný s požadovaným počtom mín. Pre test je potrebné získať počet dlaždíc typuMine
v hracom poli (napríklad do premennejmineCount
) a aplikovať testassertEquals(MINES, mineCount)
. -
Počet vygenerovaných dlaždíc typu
Clue
musí byť zhodný s počtom všetkých dlaždíc - počet mín. Pre test je potrebné získať počet dlaždíc typuClue
v hracom poli (napríklad do premennejclueCount
) a aplikovať testassertEquals(ROWS * COLUMNS - MINES, clueCount)
.
Úloha: Pridajte verejnú metóduvoid generate()
do testovacej triedyFieldTest
. Implementujte ju podľa požiadaviek uvedených v tomto bode. Overte týmto testom správnosť vygenerovania hracieho poľa. -
Počet riadkov, stĺpcov a mín v hracom poli zodpovedá zadaným počtom
-
Vymažte projekt z disku a zrušte všetky vami vytvorené nastavenia v prostredí NetBeans!
Zdroje
- Zdrojové kódy:
int getRemainingMineCount()
použite metóduint getNumberOf(Tile.State state)
triedyField
realizovanú v cvičení 5, ktorá vráti počet dlaždíc v požadovanom stave.