# Ověřování správnosti programu, ladění

- Při vytváření programů je do zdrojového kódu (neúmyslně) zaneseno mnoho různých chyb od překlepů přes neošetření hraničních případů až po logické chyby v celkovém chování programu
- Část chyb odhalí překladač (a upozorní nás na ně IDE nástroj) – chyby při překladu
- Část chyb překladač neodhalí a program jde přeložit
	- POZOR!
		- Pokud jde program přeložit, neznamená to, že funguje správně!
		- Program může (někdy nebo vždy) dávat nesprávné výsledky
		- Může docházet k chybám za běhu programu
- Chyby, které překladač neodhalí (chyby za běhu programu), je třeba najít a opravit opakovaným opravováním, překládáním a spouštěním programu s využitím vhodných vstupních dat
	- Tato činnost se nazývá ladění (častěji debugging)
- Lze provádět ručně nebo s využitím specializovaného nástroje zvaného debugger – součást téměř všech IDE nástrojů
	- Často se používá kombinace obou přístupů
- Vyšší fází ladění je testování
	- Zjišťuje se, zda program pracuje správně pro všechny typy vstupů, zda reaguje správně na neplatné vstupy apod.
	- Podrobně viz předmět KIV/OKS

### Odhalení chyb při psaní zdrojového kódu a při překladu

- Překladač ```javac``` umí odhalit především syntaktické chyby
	- Často způsobené překlepy v názvech proměnných, metod, zapomenutím na import třídy, zapomenutím deklarace proměnné, atd.
	- Všechny nalezené chyby jsou vypsány při překladu
- Překlad v příkazové řádce
	- Pokud překládáme program ručně v příkazové řádce příkazem javac, objevíme chyby až po spuštění překladu
	- Protože překlad netrvá dlouho (pro malé programy), je možné provádět ho během vývoje opakovaně, např. při každém inkrementálním přidání funkcionality
		- Nalezené chyby lze průběžně odstraňovat
		- Odstranění chyby se ověří opakovaným překladem 
	- Je možné i napsat celý program a poté odstranit chyby najednou
		- Odstranění chyb se opět ověří opakovaným překladem
	- POZOR!
		- Při opakovaném překladu se počty chyb mohou snižovat i zvyšovat
		- Překladač se snaží při překladu najít co možná nejvíce chyb  tj. neskončí při první nalezené chybě, ale pokud to jde, pokračuje dále
		- Některé chyby jsou však z pohledu překladače natolik zásadní (ač z pohledu člověka vypadají banálně – např. zapomenutý středník „;“ nebo složená závorka „}“), že mu znemožní kontrolu velké části kódu
		- Po opravení takové chyby může překladač tuto přeskočenou část zkontrolovat a tím odhalit další, dosud neodhalené chyby  počet chyb může po odstranění chyby vzrůst

#### Čtení a porozumění výstupu překladače

- Výstup překladače (tj. výpis chyb při překladu) se zobrazí po skončení překladu v příkazové řádce nebo v konzoli IDE nástroje
- Výstup nemusí být stejný v IDE a v příkazové řádce

### Ladění (debugging)

- Pokud se **program podaří přeložit**, ještě to **neznamená, že funguje správně**
	- Většinou správně nefunguje, i když jde přeložit
- Chyby v chování programu neodhalí překladač, musí je najít sám programátor
- Chybné chování programu se typicky projevuje:
	- Program je předčasně ukončen s chybovým hlášením (vždy nebo někdy)
		- Je třeba rozumět chybovému hlášení
	- Program zdánlivě funguje, ale dává pro některé či všechny vstupy zcela špatné nebo částečně špatné výsledky
	- Ladění je možno provádět ručně tzv. metodou ladících výpisů a/nebo s využitím specializovaného ladícího nástroje (debuggeru)
	- POZOR!
		- Program se nedá považovat za odladěný po vyzkoušení jednoho či několika málo vstupů
		- Je potřeba zkoušet více různých vstupních hodnot, netypické hodnoty apod.
		- Je potřeba zkoušet i neplatné hodnoty, na něž by měl program adekvátně reagovat
			- To však zatím není probráno

#### Chybové hlášení za běhu programu

- Pokud dojde za běhu programu k chybě (přesněji k vyhození výjimky) a tato chyba není v programu ošetřena, program je předčasně ukončen a do konzole (či příkazové řádky) se vypíše chybové hlášení
- Chybové hlášení
	- Vypíše, o jakou chybu (výjimku) se jedná (její název a někdy i popis)
	- Vypíše tzv. stack trace (výpis zásobníku)
		- Zjednodušený obsah zásobníku (stack) programu v okamžiku, kdy k chybě došlo
		- Obsahuje volání metod – je jasné, v jaké metodě přesně došlo k chybě (první uvedená metoda) a ze které metody byla tato metoda volána (další uvedená metoda)
		- Následují další metody, které byly hierarchicky volány až k metodě ```main()```
		- V jednoduchých programech je většinou zobrazeno i číslo řádky, na které k chybě došlo
	- Hlášení o chybách za běhu programu typicky vypadají stejně v příkazové řádce i v konzoli IDE nástroje

#### Metoda ladících výpisů

- Metoda ladících výpisů se používá, **pokud nemáme k dispozici debugger**, nebo ho z nějakého důvodu nechceme použít
- Na vhodná místa programu vložíme volání metody System.out.println()
	- Můžeme vypisovat hodnoty důležitých proměnných
	- Můžeme pomocí výpisu unikátních značek (tj. textů) určit, kde se program
- přesně nachází (podle toho, co a v jakém pořadí program vypíše)

#### Použití debuggeru v Eclipse

- Debugger umožňuje dělat automaticky to, co musíme ručn pomocí kontrolních výpisů a umožňuje mnohem více
	- Sledování hodnot vybraných proměnných a výrazů
	- Krokování programu řádku po řádce
	- Nastavení breakpointů – bodů, ve kterých se program zastaví a umožní od něj krokování 
- Spuštění debuggeru v Eclipse
	- Vytvoření breakpointu
		- Pro zapnutí debuggeru je potřeba nastavit breakpoint, tedy bod, od kterého bude program krokován
		- Breakpoint se na určitou řádku nastaví dvojklikem vlevo od požadované řádky
		- Alternativou je kliknout pravým tlačítkem na stejné místo => vybrat Toogle breakpoint
		- Přítomnost breakpointu na řádce je indikována symbolem
		- Stejným způsobem lze breakpoint odstranit
	- Spuštění debuggeru
		- Mít aktivní třídu s breakpointem
		- Debug as… => Java Application
		- Pokud si Eclipse není jistý, který program chcete debuggovat, dá vám na výběr
		- Pokud není zvolen žádný breakpoint, program proběhne jako při normálním spuštění
	- Po spuštění debuggeru program běží normálně, dokud nedosáhne breakpointu
		- Potom se objeví dotaz, zda chceme spustit debug perspektivu, která přepne rozložení oken Eclipse 
- Popis debug perspektivy v Eclipse
	- Okno zásobníku
		- Ukazuje, v jaké části programu se právě nacházíme
		- Jde o zobrazení části paměti zásobník obsahující rámce pro jednotlivé volání metod
		- Toto okno příliš nevyužíváme
	- Okno editoru
		- Okno se zdrojovým kódem
		- V debug perspektivě se zpravidla nepoužívá pro úpravu kódu
		- Zelený pruh určuje řádku, na které se program právě nachází při jeho krokování
		- Jsou vidět nastavené breakpointy
		- Nejdůležitější okno debuggeru
	- Okno se strukturou programu (outline)
		- Zobrazuje strukturu programu (jednotlivé třídy a metody)
		- Toto okno příliš nevyužíváme
	- Okno konzole
		- Okno, do kterého se vypisuje výstup programu
		- Uživatel zde rovněž zadává vstup programu, pokud je třeba
	- Okno sledování proměnných
		- Zde můžeme sledovat všechny proměnné a jejich aktuální hodnoty během krokování programu
		- Druhé nejdůležitější okno debuggeru
		- V záložce Breakpoints je seznam všech nastavených breakpointů
- Ovládání debuggeru
	- V okamžiku, kdy se program zastaví na breakpointu, lze pokračovat v jeho krokování různými způsoby
		- Step Into - též klávesa [F5]
			- Provede jeden krok programu
			- Pokud je tímto krokem volání metody, skočí do této metody
		- Step Over – též klávesa [F6]
			- Provede jeden krok programu
			- Pokud je tímto krokem volání metody, provede ji celou jako jeden krok (tj. do metody neskočí) 
		- Step Return – též klávesa [F7]
			- Provede všechny zbývající příkazy v metodě, vyskočí z ní a zastaví se na dalším řádku volající metody
		- Resume – též klávesa [F8]
			- Provede všechny příkazy od aktuální pozice až k dalšímu breakpointu (nebo do ukončení programu) normálně (tj. bez krokování)
		- Terminate – též [Ctrl]+[F2]
			- Ukončí provádění programu
	- Nastavení filtrů krokování (step filters)
		- Umožní omezit, do kterých metod je možné při krokování skočit
			- Např. nechceme, abychom se při krokování dostali do knihovních tříd a metod Java Core API
		- Zapnutí filtrů krokování (Use Step Filters – též [Ctrl]+[F5])
			- Pokud je tlačítko zapnuté, filtry jsou použity a do vybraných balíků nevstoupí ani možnost Step Into
		- Sledování hodnot proměnných (okno sledování proměnných)
			- Záložka Variables
			- Automaticky zobrazuje platné lokální proměnné a jejich hodnoty
			- Pro zobrazení statických proměnných a konstant je nutné je zaškrtnout
				- => Java => Show Constants a Show Static Variables
		- Zobrazení aktuální hodnoty proměnné
			- Stačí kurzorem myši najet v okně editoru na proměnnou, která nás zajímá 
- Díky debuggeru přesně vidíme, co se v programu děje, jaké jsou hodnoty proměnných
	- Podstatně komfortnější, než kontrolní výpisy
	- Lze vyzkoušet na odhalení chyb v programu pro výpočet faktoriálu

