← Zpět na obsah

Kapitola 11: Návrh jednoduchého programu (ověření a oprava chyb)

Testování programu - hledání a oprava chyb
Testování programu - hledání a oprava chyb

1. Úvod: Když robot dělá chyby

Představ si, že jsi naprogramoval robota, aby ti uvařil čaj. Dal jsi mu přesné instrukce (algoritmus). Ale co když robot místo čaje uvaří kávu? Nebo se mu konvice vůbec nezapne? To znamená, že v tvém programu (nebo algoritmu) je chyba! V této kapitole se naučíme, jak zkontrolovat, jestli náš program funguje správně, a co dělat, když najdeme chybu.

2. Co je to program?

Program je vlastně jen jiný název pro algoritmus, který je napsaný tak, aby mu rozuměl počítač. Je to posloupnost příkazů, které počítač provádí krok za krokem.

Definice: Program

Program je sada přesných instrukcí (algoritmus) napsaných v jazyce, kterému rozumí počítač, aby vykonal určitý úkol.

3. Ověření správnosti postupu: Funguje to?

Když něco naplánujeme nebo napíšeme program, musíme zkontrolovat, jestli to funguje tak, jak má. Tomu říkáme ověření správnosti.

Proč je to důležité?

Kdybychom neověřovali, mohli bychom si myslet, že náš program funguje, ale ve skutečnosti by dělal něco špatně. To by mohlo vést k velkým problémům.

Příklad: Ověření receptu
Napsal jsi recept na bábovku. Jak ověříš, že je správný? Upečeš bábovku podle něj! Pokud se povede, recept je správný. Pokud se nepovede, je v receptu chyba.

4. Testování programu: Zkouška ohněm

V informatice se ověřování správnosti programu říká testování. Znamená to, že program spustíme a zkusíme, jestli dělá to, co má.

Definice: Testování programu

Testování programu je proces, při kterém zkoušíme, zda program funguje správně a bez chyb.

Jak testujeme?

Příklad: Testování programu na sčítání čísel
Napsal jsi program, který má sečíst dvě čísla.

5. Rozpoznání a oprava chyby: Hledání a spravování

Když program nefunguje, jak má, znamená to, že v něm je chyba. V informatice se chybám říká bugy (z anglického "brouci"). A proces hledání a opravování chyb se nazývá ladění (debugging).

Jak rozpoznat chybu?

Jak opravit chybu?

Oprava chyby je jako hledání jehly v kupce sena. Musíš se podívat na svůj program krok za krokem a zjistit, kde jsi udělal chybu.

Ladění - od chyby k funkčnímu programu
Ladění - od chyby k funkčnímu programu

6. Testování a ladění ve Scratchi

Scratch je skvělé prostředí pro učení, protože ti umožňuje snadno testovat a opravovat programy. Pojďme si ukázat, jak to funguje!

6.1. Časté chyby ve Scratchi a jak je najít

Chyba 1: Program se nespustí

Chyba 2: Sprite se pohybuje špatně

Chyba 3: Cyklus běží věčně

6.2. Praktický příklad: Najdi a oprav chybu

Úloha: Chtěl jsi vytvořit program, který nakreslí trojúhelník.

Tvůj program (s chybou):
🟡 když se klikne na 🏴
🟢 smaž vše
🟢 pero dolů
🟠 opakuj 4x
    🔵 posuň se o 100 kroků
    🔵 otoč se doprava o 90 stupňů
Co se stane: Nakreslí se čtverec, ne trojúhelník! 😱

Kde je chyba?
Opravený program:
🟡 když se klikne na 🏴
🟢 smaž vše
🟢 pero dolů
🟠 opakuj 3x
    🔵 posuň se o 100 kroků
    🔵 otoč se doprava o 120 stupňů
Teď to funguje! ✅ Program nakreslí trojúhelník! 🎉

6.3. Tipy pro testování ve Scratchi

Člověk a digitální svět

V digitálním světě se neustále setkáváme s programy, které nám usnadňují život. Ale i ty nejlepší programy mohou mít chyby. Schopnost rozpoznat, že něco nefunguje správně, a umět požádat o pomoc nebo se pokusit chybu opravit, je důležitá pro každého uživatele. Učíme se tak kriticky přistupovat k technologiím a nenechat se odradit, když něco nefunguje na první pokus.

Otázky k zamyšlení

Úkoly pro praxi

  1. Chybný recept: Napiš jednoduchý recept na něco, co umíš uvařit (např. čaj, toust). Schválně do něj vlož jednu malou chybu (např. zapomeň na cukr, nebo zaměň pořadí kroků). Dej recept někomu jinému, aby podle něj zkusil vařit. Zjistěte, jestli chybu najde a opraví.
  2. Hledání "bugů" v denním plánu: Vytvoř si podrobný plán na zítřejší den (např. vstát v 7:00, snídaně v 7:30, škola v 8:00...). Zkus se ho držet. Na konci dne si zapiš, co se ti nepovedlo dodržet a proč. To jsou tvé "bugy" v plánu. Jak bys plán upravil, aby byl příště lepší?
  3. Testování kalkulačky: Otevři si kalkulačku v počítači nebo v mobilu. Zkus zadat různé příklady (např. 5+3, 10-2, 4*6, 10/0). Co se stane, když zkusíš dělit nulou? Je to chyba programu, nebo je to tak správně? Zkus to vysvětlit.

* Rozšíření pro pokročilé

Typy testování v software

V profesionální praxi existuje mnoho typů testování:

Debugging techniky

Test cases a test plan

Profesionální testování vyžaduje systematický přístup:

Pyramida testování - jednotkové, integrační, systémové
Pyramida testování - jednotkové, integrační, systémové

* Úkoly pro pokročilé

  1. Excel – Test cases: Vytvoř v Excelu tabulku testovacích případů pro kalkulačku. Sloupce: ID testu, Popis, Vstup 1, Operace, Vstup 2, Očekávaný výstup, Skutečný výstup, Výsledek (PASS/FAIL). Vyplň 10 testů včetně edge cases (0, záporná čísla, dělení nulou).
  2. Word – Bug report: Vytvoř šablonu bug reportu ve Wordu: Název bugu, Závažnost (kritická/vysoká/střední/nízká), Kroky k reprodukci, Očekávaný výsledek, Skutečný výsledek, Screenshot, Návrh opravy.
  3. Scratch – Debugging: Vytvoř ve Scratchi program s úmyslnými 3 chybami. Dej ho spolužákovi. Ať najde a opraví všechny chyby. Pak si role vyměňte.
  4. Scratch – Automatizované testování: Vytvoř ve Scratchi blok "Test_Sčítání", který automaticky otestuje, zda 2+2=4, 5+3=8, atd. Pokud test projde, zobraz zelený symbol, pokud ne, červený.

** Rozšíření pro maturitní obory

Podrobně: Metodiky testování

Black-box vs White-box testování

Testovací techniky

TDD (Test-Driven Development)

  1. Napiš test (zatím selže – červená).
  2. Napiš minimální kód, aby test prošel (zelená).
  3. Refaktoruj kód (zlepši, zachovej funkčnost).
  4. Opakuj.

Debugging v praxi

Profesionální vývojáři používají debuggery:

TDD cyklus - červená, zelená, refaktoring
TDD cyklus - červená, zelená, refaktoring

** Úkoly pro maturitní obory

  1. Flowgorithm – Program s validací: Vytvoř algoritmus pro výpočet BMI (váha / výška²). Přidej validaci: váha 30-300 kg, výška 0.5-2.5 m. Pokud jsou vstupy mimo rozsah, zobraz chybu.
  2. Flowgorithm – Testovací případy: Pro algoritmus výpočtu věku z roku narození vytvoř a otestuj edge cases: rok v budoucnosti, rok moc starý, aktuální rok, záporné číslo.
  3. Excel – Test plan: Vytvoř komplexní testovací plán pro e-shop. Zahrň: přihlášení, vyhledávání, košík, platba. Pro každou oblast napiš 5+ testovacích případů.
  4. Word – Dokumentace bugu: Najdi skutečnou chybu v nějaké aplikaci (nebo web stránce). Napiš profesionální bug report podle šablony.
  5. PowerPoint – Testovací strategie: Vytvoř prezentaci "Jak testovat software" (10-12 snímků). Zahrň: typy testů, techniky, TDD, nástroje.
  6. Canva – Checklist testera: Vytvoř v Canvě jednostránkový checklist pro testera: co testovat před vydáním software (A4 pro tisk).

*** Rozšíření pro IT obory

Jako IT specialista budeš psát testy jako součást své každodenní práce. Naučíš se používat testovací frameworky a automatizovat testování.

Unit testy v Pythonu (pytest)

pytest je nejpopulárnější testovací framework pro Python:

# kalkulacka.py - kód k testování
def secti(a, b):
    return a + b

def odecti(a, b):
    return a - b

def vydel(a, b):
    if b == 0:
        raise ValueError("Nelze dělit nulou")
    return a / b
        
# test_kalkulacka.py - testy
import pytest
from kalkulacka import secti, odecti, vydel

def test_secti_kladna_cisla():
    assert secti(2, 3) == 5

def test_secti_zaporna_cisla():
    assert secti(-1, -1) == -2

def test_odecti():
    assert odecti(5, 3) == 2

def test_vydel():
    assert vydel(10, 2) == 5

def test_vydel_nulou():
    with pytest.raises(ValueError):
        vydel(10, 0)

# Spuštění: pytest test_kalkulacka.py
        

TDD (Test-Driven Development)

TDD je metodika, kde nejdřív napíšeš test, pak kód:

# Krok 1: RED - napiš test, který selže
def test_je_prvocislo():
    assert je_prvocislo(2) == True
    assert je_prvocislo(7) == True
    assert je_prvocislo(4) == False
    assert je_prvocislo(1) == False

# Krok 2: GREEN - napiš minimální kód, aby test prošel
def je_prvocislo(n):
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

# Krok 3: REFACTOR - vylepši kód, testy stále procházejí
        

Debugging v IDE

Profesionální vývojáři používají debugger v IDE (VS Code, PyCharm):

# Příklad pro debugging
def najdi_chybu(seznam):
    vysledek = []
    for i in range(len(seznam)):
        if seznam[i] > 0:
            vysledek.append(seznam[i] * 2)  # Nastav breakpoint zde
    return vysledek

# Spusť s debuggerem a sleduj, co se děje
data = [1, -2, 3, -4, 5]
print(najdi_chybu(data))
        

Automatizace testů (CI/CD)

V profesionálním prostředí se testy spouštějí automaticky při každé změně kódu:

# .github/workflows/test.yml - GitHub Actions
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.9'
      - name: Install dependencies
        run: pip install pytest
      - name: Run tests
        run: pytest
        

*** Praktické úkoly pro IT obory

  1. pytest: Nainstaluj pytest (pip install pytest). Napiš modul s 3 funkcemi a k němu testovací soubor s alespoň 6 testy.
  2. TDD: Použij TDD pro vytvoření funkce validuj_email(). Nejdřív napiš testy (platné a neplatné emaily), pak implementuj funkci.
  3. Debugging: Stáhni program s úmyslnými chybami. Pomocí debuggeru v IDE najdi a oprav všechny chyby.
  4. Code coverage: Nainstaluj pytest-cov. Spusť testy s měřením pokrytí. Dosáhni alespoň 80% pokrytí kódu testy.

*** Projekt pro IT obory: Správce kontaktů (část 2/4)

Pokračujeme v projektu Správce kontaktů. V této kapitole přidáme správce kontaktů, ukládání do souboru a testy.

Krok 5: Správce kontaktů (models/spravce.py)

# models/spravce.py
"""Modul pro správu kolekce kontaktů."""

import json
from models.kontakt import Kontakt

class SpravceKontaktu:
    """Třída pro správu seznamu kontaktů."""

    def __init__(self, soubor="data/kontakty.json"):
        """
        Inicializace správce.

        Args:
            soubor: Cesta k souboru pro ukládání
        """
        self.soubor = soubor
        self.kontakty = []
        self.nacti()

    def pridej(self, kontakt):
        """Přidá nový kontakt."""
        self.kontakty.append(kontakt)
        self.uloz()

    def odeber(self, jmeno):
        """Odebere kontakt podle jména."""
        puvodni_delka = len(self.kontakty)
        self.kontakty = [k for k in self.kontakty
                         if k.jmeno.lower() != jmeno.lower()]
        if len(self.kontakty) < puvodni_delka:
            self.uloz()
            return True
        return False

    def vyhledej(self, dotaz):
        """Vyhledá kontakty obsahující dotaz v jménu nebo telefonu."""
        dotaz = dotaz.lower()
        return [k for k in self.kontakty
                if dotaz in k.jmeno.lower() or dotaz in k.telefon]

    def zobraz_vsechny(self):
        """Vrátí seznam všech kontaktů."""
        return self.kontakty

    def uloz(self):
        """Uloží kontakty do JSON souboru."""
        import os
        os.makedirs(os.path.dirname(self.soubor), exist_ok=True)

        data = [k.to_dict() for k in self.kontakty]
        with open(self.soubor, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)

    def nacti(self):
        """Načte kontakty z JSON souboru."""
        try:
            with open(self.soubor, "r", encoding="utf-8") as f:
                data = json.load(f)
                self.kontakty = [Kontakt.from_dict(d) for d in data]
        except FileNotFoundError:
            self.kontakty = []
        

Krok 6: Testy (tests/test_kontakt.py)

# tests/test_kontakt.py
"""Testy pro modul Kontakt."""

import pytest
from models.kontakt import Kontakt

def test_vytvoreni_kontaktu():
    """Test vytvoření kontaktu."""
    k = Kontakt("Jan Novák", "123456789", "jan@email.cz")
    assert k.jmeno == "Jan Novák"
    assert k.telefon == "123456789"
    assert k.email == "jan@email.cz"

def test_kontakt_bez_emailu():
    """Test kontaktu bez emailu."""
    k = Kontakt("Eva Černá", "987654321")
    assert k.email == ""

def test_str_reprezentace():
    """Test textové reprezentace."""
    k = Kontakt("Jan", "123")
    assert "Jan" in str(k)
    assert "123" in str(k)

def test_to_dict():
    """Test převodu na slovník."""
    k = Kontakt("Jan", "123", "jan@test.cz")
    d = k.to_dict()
    assert d["jmeno"] == "Jan"
    assert d["telefon"] == "123"
    assert d["email"] == "jan@test.cz"

def test_from_dict():
    """Test vytvoření ze slovníku."""
    d = {"jmeno": "Eva", "telefon": "456", "email": "eva@test.cz"}
    k = Kontakt.from_dict(d)
    assert k.jmeno == "Eva"
    assert k.telefon == "456"
        

Krok 7: Spuštění testů

# Nainstaluj pytest
pip install pytest

# Spusť testy
pytest tests/

# Spusť s podrobným výstupem
pytest tests/ -v

# Spusť s měřením pokrytí
pip install pytest-cov
pytest tests/ --cov=models
        

Krok 8: Commit změn

# Zkontroluj změny
git status
git diff

# Přidej a commitni
git add .
git commit -m "Přidán správce kontaktů a testy

- Implementována třída SpravceKontaktu
- Ukládání a načítání z JSON
- Vyhledávání kontaktů
- Přidány unit testy pro Kontakt"

# Nahraj na GitHub
git push
        

Aktuální struktura projektu

spravce-kontaktu/
├── .git/
├── .gitignore
├── README.md
├── models/
│   ├── __init__.py
│   ├── kontakt.py         # ✓ Třída Kontakt
│   └── spravce.py         # ✓ NOVÉ - SpravceKontaktu
├── utils/
│   └── __init__.py
├── tests/
│   ├── __init__.py
│   └── test_kontakt.py    # ✓ NOVÉ - Testy
└── data/                  # Vytvoří se automaticky
    └── kontakty.json
        

*** Úkol pro tuto kapitolu

  1. Implementuj SpravceKontaktu podle kódu výše.
  2. Napiš a spusť testy pomocí pytest.
  3. Přidej testy pro SpravceKontaktu (tests/test_spravce.py).
  4. Vytvoř commit a nahraj na GitHub.

V další kapitole: Přidáme hlavní program s menu (CLI interface).

← Zpět na obsah