148 lines
9.7 KiB
Markdown
148 lines
9.7 KiB
Markdown
|
# 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
|
|||
|
|