Programování

Systematické debugování – metoda místo náhodného zkoušení

Jak hledat chyby metodicky – reprodukce, hypotézy, bisekce, debugger a git bisect. Konkrétní postup a nástroje pro Python, JavaScript i server.

12. 10. 2026 · 4 min čtení

Debugování „metodou pokus–omyl“ funguje u malých chyb. U těch zákeřných vede k hodinám přepisování kódu, které nic nevyřeší. Systematický přístup je pomalejší na prvních pět minut a mnohem rychlejší celkově. Tady je postup, který funguje pro webovou aplikaci, skript i serverovou službu.

Krok 1: spolehlivě chybu reprodukujte

Chyba, kterou neumíte vyvolat, se nedá spolehlivě opravit – nevíte, jestli oprava zabrala. Zapište si:

  • Přesné kroky k vyvolání.
  • Očekávané chování vs. skutečné chování.
  • Prostředí – verze jazyka, OS, prohlížeč, data.

Cíl je zmenšit reprodukci na minimum: místo „po kliknutí na objednávku v administraci“ mít „funkce calculate_vat(Decimal('0.1')) vrací 0“. Nejlepší je minimální reprodukci rovnou zapsat jako test – po opravě zůstane jako ochrana před návratem chyby.

Krok 2: přečtěte, co máte

Než začnete měnit kód, projděte celou chybovou hlášku, stack trace a logy. Spousta chyb je vyřešena tím, že si člověk konečně přečte druhý řádek výpisu.

Užitečné příkazy pro hledání v logu:

journalctl -u myapp --since "10 min ago" --no-pager
grep -n "ERROR" /var/log/myapp/app.log | tail -20
tail -f /var/log/nginx/error.log

Krok 3: formulujte hypotézu a ověřte ji

Neměňte kód naslepo. Formulujte konkrétní tvrzení: „Myslím, že user je None, protože session vypršela.“ Pak navrhněte pokus, který hypotézu potvrdí nebo vyvrátí:

  • výpis hodnoty v daném místě,
  • breakpoint v debuggeru,
  • test s okrajovým vstupem.

Každý pokus zapisujte. Po hodině debugování si jinak nepamatujete, co už jste vyloučili.

Krok 4: zužujte prostor (bisekce)

Když nevíte, kde chyba je, dělte problém napůl:

  • Data: funguje to s prvními 500 záznamy? S druhou půlkou?
  • Kód: zakomentujte polovinu pipeline – projde to?
  • Konfigurace: vraťte polovinu změn.

Každý krok vyloučí půlku možností. Ze 1000 podezřelých míst se na jedno dostanete zhruba za 10 kroků.

git bisect: bisekce v historii

Když „to minulý týden fungovalo“, nechte git najít commit, který chybu zavedl:

git bisect start
git bisect bad                 # aktuální stav je rozbitý
git bisect good v1.4.0         # tahle verze fungovala
# git přepne na commit uprostřed – otestujte a označte:
git bisect good   # nebo: git bisect bad
# … opakujte, dokud git nevypíše první špatný commit
git bisect reset

Pokud máte test, který chybu odhalí, lze bisekci plně automatizovat:

git bisect run pytest tests/test_vat.py -x

Skript musí vrátit 0 pro „dobrý“ a nenulový kód (kromě 125, který znamená „přeskočit“) pro „špatný“.

Krok 5: používejte debugger, ne jen print

print je v pořádku, ale debugger vám ukáže všechny proměnné a dovolí krokovat.

Python – vestavěná funkce breakpoint() (Python 3.7+) zastaví program v pdb:

def calculate_vat(amount, rate):
    breakpoint()
    return amount * rate

Základní příkazy pdb: n (další řádek), s (vstoupit do funkce), c (pokračovat), p promenna (vypsat), l (zobrazit kód), w (stack), q (konec).

Node.js:

node --inspect-brk server.js

Pak otevřete v Chromu chrome://inspect nebo použijte debugger ve VS Code. V kódu funguje příkaz debugger;.

Prohlížeč: DevTools → Sources → klik na číslo řádku. Užitečné jsou podmíněné breakpointy (pravý klik → Add conditional breakpoint), např. order.id === 1042.

Krok 6: ověřte opravu a příčinu

Oprava je hotová, když:

  1. Původní reprodukce už chybu nevyvolá.
  2. Rozumíte, proč chyba vznikla. „Přidal jsem if x is not None a funguje to“ není pochopení – proč tam byl None?
  3. Existuje test, který by chybu příště zachytil.
  4. Prověřili jste, zda stejná chyba není jinde (podobný kód, zkopírovaná funkce).

Časté pasti

  • Měníte víc věcí naráz. Pak nevíte, co pomohlo. Jedna změna, jeden pokus.
  • Debugujete jiný kód, než běží. Cache, neprovedený restart služby, starý build, jiné virtuální prostředí. Ověřte si to – přidejte zjevný log a zkontrolujte, že se objeví.
  • Věříte předpokladům. „Tahle funkce určitě vrací seznam.“ Ověřte to.
  • Neviditelné rozdíly: mezery na konci řetězce, \r\n vs. \n, časová pásma, 0.1 + 0.2 != 0.3 u floatů.

Gumová kachnička a AI

Vysvětlení problému nahlas – třeba gumové kachničce na stole – často odhalí chybu, protože vás donutí projít předpoklady jeden po druhém. Stejně funguje i dobře napsaný dotaz na AI: popište reprodukci, očekávání, skutečnost a co už jste vyloučili. Režim Řešení problémů v ColdHost AI je postavený přesně na takovém postupném hledání příčiny.