Skip to content

Instantly share code, notes, and snippets.

@tuttle
Created May 12, 2026 08:51
Show Gist options
  • Select an option

  • Save tuttle/edb923fe56ec40e0742882f148233e6f to your computer and use it in GitHub Desktop.

Select an option

Save tuttle/edb923fe56ec40e0742882f148233e6f to your computer and use it in GitHub Desktop.

Property-based testing

Property-based testing (PBT) je moderní přístup k testování softwaru, který převrací klasické psaní testů naruby. Místo toho, abys vymýšlel konkrétní vstupy (např. "co se stane, když zadám číslo 5"), definuješ vlastnosti (properties), které by měl tvůj kód splňovat pro jakýkoliv platný vstup.

Knihovna Hypothesis je pro Python v tomto směru naprostým standardem a špičkou v oboru.


1. Rozdíl mezi klasickým testem a PBT

V běžném testu (např. v pytest) píšeš tzv. example-based testy:

  • Vstup: 2 a 3.
  • Očekávaný výsledek: Součet je 5.

V property-based testu pomocí Hypothesis:

  • Vstup: Jakákoliv dvě celá čísla ($x, y$).
  • Vlastnost: Součet $x + y$ musí být stejný jako $y + x$ (komutativita).

2. Jak funguje Hypothesis?

Hypothesis za tebe generuje stovky náhodných testovacích případů, které odpovídají tvé definici dat. Pokud najde chybu, provede tzv. shrinking (zmenšování). To znamená, že se snaží najít nejjednodušší možný příklad, který chybu stále vyvolává (např. místo obrovského seznamu s tisíci prvky ti ukáže, že kód padá už při seznamu s jedním prvkem [0]).


3. Praktická ukázka v Pythonu

Představ si, že máš funkci, která má seřadit seznam čísel.

from hypothesis import given, strategies as st

def sort_numbers(numbers):
    # Představme si, že tady je naše implementace
    return sorted(numbers)

@given(st.lists(st.integers()))
def test_sort_numbers_properties(numbers):
    result = sort_numbers(numbers)
    
    # Vlastnost 1: Výsledek má stejnou délku jako vstup
    assert len(result) == len(numbers)
    
    # Vlastnost 2: Prvky v seznamu jsou seřazeny (každý je menší nebo roven následujícímu)
    for i in range(len(result) - 1):
        assert result[i] <= result[i+1]
        
    # Vlastnost 3: Výsledek obsahuje stejné prvky jako originál
    assert sorted(result) == sorted(numbers)

Co se v kódu děje:

  • @given(...): Dekorátor, který říká Hypothesis, co má generovat.
  • st.lists(st.integers()): Strategie, která říká: „Vytvoř seznamy náhodných celých čísel libovolné délky.“
  • Hypothesis tento test spustí typicky 100x s různými bizarními hodnotami (prázdný seznam, záporná čísla, extrémně velká čísla).

4. Hlavní výhody

  • Najde "Edge Cases": Člověk často zapomene otestovat prázdný řetězec, nulu nebo speciální znaky. Hypothesis na ně nezapomene nikdy.
  • Shrinking: Když test selže, Hypothesis ti nevyhodí jen chybu, ale ten nejmenší možný vstup, který ji způsobil. To drasticky zrychluje ladění.
  • Dokumentace vlastností: Nutí tě přemýšlet o tom, co tvůj kód skutečně garantuje, nejen jaké dává výsledky pro pár čísel.

5. Kdy PBT použít?

Není nutné psát PBT pro všechno. Nejvíce zazáří u:

  1. Algoritmů (řazení, vyhledávání, transformace dat).
  2. Parsování a serializace (např. JSON -> objekt -> JSON by se nemělo změnit).
  3. Integrace a API, kde očekáváš určitý formát dat.

Máš nějaký konkrétní kód nebo funkci, u které přemýšlíš, jak ji otestovat pomocí vlastností?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment