# 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